public bool Parse(TokensReader expression, bool expression_end) { body = null; haveIf = false; if (expression.tokens.Pop() == TokenType.ELSE) { TokensReader backup = new TokensReader(); backup.Add(expression); try { if (ift.Parse(expression, expression_end)) { haveIf = true; return(true); } } finally { } if (expression_end) { body = backup; } return(true); } else { return(false); } }
public static Type ParseSmallStatement(ref TokensReader expression) { int thisStatement = lvlStatement; lvlStatement++; List <Type> valuetypes = new List <Type>(); while (thisStatement < lvlStatement) { valuetypes.Add(ParseValue(ref expression)); } valuetypes.RemoveLast(); // remove type which was getted of close statement if (valuetypes.IsEmpty()) { return(typeof(void)); } else if (valuetypes.Count == 1) { return(valuetypes[0]); } else { return(valuetypes[valuetypes.Count / 2]); } }
public bool Parse(TokensReader expression, bool expression_end) { typename = ""; varnames = new List <string>(); type = VarType.DEFAULT; security = SecurityDegree.PUBLIC; if (expression_end && expression.tokens.Pop() == TokenType.VAR) { type = expression.var_types.Pop(); security = expression.securities.Pop(); if (expression.tokens.Pop() == TokenType.LITERAL) { typename = expression.string_values.Pop(); parse_var: if (expression.tokens.Pop() == TokenType.LITERAL) { varnames.Add(expression.string_values.Pop()); TokenType token; try { token = expression.tokens.Pop(); } catch (ArgumentOutOfRangeException) // if tokens is ended { return(true); } if (token == TokenType.SEPARATOR) { if (expression.bool_values.Pop()) { return(false); } else { goto parse_var; } } else { return(false); } } else { return(false); } } else { return(false); } } else { return(false); } }
public static LocalBuilder ParseLocal(ref TokensReader expression) { if (expression.tokens.Pop() == TokenType.LITERAL) { return(Context.functionBuilder.GetLocal(expression.string_values.Pop())); } else { return(null); } }
public bool Parse(TokensReader expression, bool expression_end) { if (expression_end && expression.tokens[0] == TokenType.IMPORT_LIBRARY && expression.tokens.Count == 1) { path = expression.string_values.Pop(); return(true); } else { return(false); } }
public static void Add(this TokensReader a, TokensReader b) { a.tokens.AddRange(b.tokens); a.var_types.AddRange(b.var_types); a.values.AddRange(b.values); a.string_values.AddRange(b.string_values); a.securities.AddRange(b.securities); a.operators.AddRange(b.operators); a.loops.AddRange(b.loops); a.function_types.AddRange(b.function_types); a.byte_values.AddRange(b.byte_values); a.bool_values.AddRange(b.bool_values); }
public bool Parse(TokensReader expression, bool expression_end) { if (expression_end && expression.tokens[0] == TokenType.NAMESPACE && expression.tokens.Count == 1) { ns = expression.string_values.Pop(); return(true); } else { return(false); } }
/// <summary> /// Reads an OpenLisp.NET atom. /// </summary> /// <param name="reader"></param> /// <returns></returns> public static OpenLispVal ReadAtom(TokensReader reader) { string token = reader.Next(); string pattern = @"(^-?[0-9]+$)|(^-?[0-9][0-9.]*$)|(^nil$)|(^true$)|(^false$)|^("".*"")$|:(.*)|(^[^""]*$)"; Regex regex = new Regex(pattern); Match match = regex.Match(token); //Console.WriteLine("token: ^" + token + "$"); if (!match.Success) { throw new ParseError("unrecognized token '" + token + "'"); } if (match.Groups[1].Value == String.Empty) { if (match.Groups[3].Value == String.Empty) { if (match.Groups[4].Value == String.Empty) { if (match.Groups[5].Value == String.Empty) { if (match.Groups[6].Value == String.Empty) { if (match.Groups[7].Value == String.Empty) { if (match.Groups[8].Value == String.Empty) { throw new ParseError("unrecognized '" + match.Groups[0] + "'"); } return(new OpenLispSymbol(match.Groups[8].Value)); } return(new OpenLispString("\u029e" + match.Groups[7].Value)); } string str = match.Groups[6].Value; str = str.Substring(1, str.Length - 2) .Replace("\\\"", "\"") .Replace("\\n", "\n"); return(new OpenLispString(str)); } return(StaticOpenLispTypes.False); } return(StaticOpenLispTypes.True); } return(StaticOpenLispTypes.Nil); } return(new OpenLispInt(int.Parse(match.Groups[1].Value))); }
public static string ParseLiterals(ref TokensReader expression) { TokenType token = expression.tokens.Pop(); if (token == TokenType.LITERAL) { bool mustLiteral = true; StringBuilder literals = new StringBuilder(); while (token == TokenType.LITERAL || token == TokenType.SEPARATOR) { if (mustLiteral && token == TokenType.LITERAL) { literals.Append(expression.string_values.Pop()); mustLiteral = false; } else if (!mustLiteral && token == TokenType.SEPARATOR) { mustLiteral = true; if (expression.bool_values.Pop()) { literals.Append("."); } else { expression.bool_values.Insert(0, false); break; } } else { break; } token = expression.tokens.Pop(); } if (mustLiteral) { errors.Add(new InvalidTokenError(line, "After separator must be literal")); } else { expression.tokens.Insert(0, token); return(literals.ToString()); } } else { expression.tokens.Insert(0, token); } return(null); }
public static FieldInfo ParseField(ref TokensReader expression) { errors = new List <TokensError>(); string varName = ParseLiterals(ref expression); if (varName != null) { FieldInfo field = Context.GetVarByName(varName); if (field == null) { errors.Add(new VarNotFoundError(line, $"Field with name {varName} not found")); } return(field); } else { return(null); } }
public bool Parse(TokensReader expression, bool expression_end) { body = null; TokenType token = expression.tokens.Pop(); if (token == TokenType.IF) { statement = PartTemplate.ParseStatement(ref expression); if (expression_end) { body = expression; } return(true); } else { return(false); } }
public static Type ParseStatement(ref TokensReader expression) { TokenType token = expression.tokens.Pop(); if (token == TokenType.STATEMENT) { if (expression.bool_values.Pop()) { return(ParseSmallStatement(ref expression)); } else { errors.Add(new InvalidTokenError(line, $"There are wrong 'closing statement' token")); } } else { expression.tokens.Insert(0, token); errors.Add(new InvalidTokenError(line, $"Statement cannot start with token {token}")); } return(null); }
public bool Parse(TokensReader expression, bool expression_end) { field = null; local = null; valuetype = null; if (expression.tokens.Pop() == TokenType.LITERAL && expression_end) { expression.tokens.Insert(0, TokenType.LITERAL); TokensReader backup = new TokensReader(); backup.Add(expression); local = PartTemplate.ParseLocal(ref expression); if (local == null) // is field { expression = backup; field = PartTemplate.ParseField(ref expression); } if (expression.tokens.Pop() == TokenType.OPERATOR && expression.operators.Pop() == OperatorType.ASSIGN) { valuetype = PartTemplate.ParseValue(ref expression); if (expression.tokens.Count == 0) { return(true); } else { return(false); } } else { return(false); } } else { return(false); } }
/// <summary> /// Reads an OpenLisp.NET list expression. /// </summary> /// <param name="reader"></param> /// <param name="openLispList"></param> /// <param name="start"></param> /// <param name="end"></param> /// <returns></returns> public static OpenLispVal ReadList(TokensReader reader, OpenLispList openLispList, char start, char end) { string token = reader.Next(); if (token[0] == start) { while ((token = reader.Peek()) != null && token[0] != end) { openLispList.Conj(ReadForm(reader)); } if (token == null) { throw new ParseError("expected '" + end + "', got EOF"); } reader.Next(); return(openLispList); } throw new ParseError("expected '" + start + "'"); }
public static Type ParseNewObject(ref TokensReader expression) { string ctorName = ParseLiterals(ref expression); if (ctorName != null) { Type type = Context.GetTypeByName(ctorName); TokenType token = expression.tokens.Pop(); if (token == TokenType.STATEMENT) { if (expression.bool_values.Pop()) { token = expression.tokens.Pop(); if (token == TokenType.STATEMENT && !expression.bool_values.Pop()) // empty arguments { LaterCalls.NewObject(type.GetConstructor(Type.EmptyTypes)); return(type); } else { expression.tokens.Insert(0, token); List <Type> paramTypes = new List <Type>(); parse_param: Type paramType = ParseValue(ref expression); if (paramType == null) { return(null); } else { paramTypes.Add(paramType); token = expression.tokens.Pop(); if (token == TokenType.STATEMENT) { if (!expression.bool_values.Pop()) { LaterCalls.NewObject(type.GetConstructor(paramTypes.ToArray())); return(type); } else { expression.bool_values.Insert(0, true); } } else if (token == TokenType.SEPARATOR && !expression.bool_values.Pop()) { goto parse_param; } else { return(null); } } return(null); } } else { errors.Add(new InvalidTokenError( line, $"After constructor name must stay open statement (not close)")); } } else { errors.Add(new InvalidTokenError( line, $"After constructor name must stay open statement (not {token})")); } } return(null); }
public Generator() { directives.Add("extends", () => { TokenType curToken = reader.tokens.Pop(); if (curToken == TokenType.LITERAL) { if (Config.header == HeaderType.CLASS) { Context.mainClass.Extends(reader.string_values.Pop()); } else { errors.Add(new InvalidHeaderError(line, Config.header, "extends directive can be only with class header")); } } else { errors.Add(new InvalidTokenError(line, curToken)); } }); directives.Add("implements", () => { TokenType tokenType = TokenType.LITERAL; while (tokenType != TokenType.NEWLN) { if (Config.header == HeaderType.CLASS) { Context.mainClass.Implements(reader.string_values.Pop()); } else { errors.Add(new InvalidHeaderError(line, Config.header, "implements directive can be only with class header")); } } }); directives.Add("if", () => { //something }); directives.Add("endif", () => { //something }); directives.Add("outtype", () => { string outType = reader.string_values.Pop(); if (!Enum.TryParse(outType, out Config.outputType)) { errors.Add(new InvalidOutTypeError(line, outType)); } }); directives.Add("try", () => { tryDirective = true; }); directives.Add("endtry", () => { tryDirective = false; tryPositions.Push(expression.tokens.Count); tryCounts.Push(tryTokens.Count - tryCounts.Sum()); expression.tokens.Add(tryTokens.Last()); }); strongTemplates.Add(TokenType.INCLUDE, new IncludeTemplate()); strongTemplates.Add(TokenType.USING_NAMESPACE, new UseTemplate()); strongTemplates.Add(TokenType.IMPORT_LIBRARY, new LibTemplate()); strongTemplates.Add(TokenType.NAMESPACE, new NamespaceTemplate()); strongTemplates.Add(TokenType.BREAKPOINT, new BreakpointTemplate()); strongTemplates.Add(TokenType.VAR, new VarTemplate()); strongTemplates.Add(TokenType.IF, new IfTemplate()); strongTemplates.Add(TokenType.ELSE, new ElseTemplate()); flexTemplates.Add(new CallMethodTemplate()); flexTemplates.Add(new AssignTemplate()); flexTemplates.Add(new WhileTemplate()); reader = new TokensReader(); }
/// <summary> /// Get expression from code /// </summary> public void TakeExpression() { expression = new TokensReader(); exprend = true; int pos = 0; while (pos < reader.tokens.Count) { pos++; TokenType token; try { token = reader.tokens[pos]; } catch (ArgumentOutOfRangeException) { break; } if (tryDirective) { if (token != TokenType.DIRECTIVE) { tryTokens.Add(token); } } if (token == TokenType.EXPRESSION_END || token == TokenType.BLOCK) { if (token == TokenType.EXPRESSION_END) { exprend = true; } else { if (reader.bool_values.Pop()) { exprend = false; needEndBlock++; } else { if (expression.tokens.IsEmpty()) { needEndBlock--; } else { errors.Add(new NeedEndError(line, "Doesnt close expression before closing block")); } } } break; } else if (token == TokenType.NEWLN) { line++; } else if (token == TokenType.DIRECTIVE) { pos = ParseDirective(++pos); } else { if (!tryDirective) { expression.tokens.Add(token); } if (token == TokenType.CLASS) { expression.string_values.Add(reader.string_values.Pop()); expression.class_types.Add(reader.class_types.Pop()); expression.securities.Add(reader.securities.Pop()); } else if (token == TokenType.FUNCTION) { expression.string_values.Add(reader.string_values.Pop()); expression.string_values.Add(reader.string_values.Pop()); expression.function_types.Add(reader.function_types.Pop()); expression.securities.Add(reader.securities.Pop()); } else if (token == TokenType.VAR) { expression.var_types.Add(reader.var_types.Pop()); expression.securities.Add(reader.securities.Pop()); } else if (token == TokenType.STATEMENT || token == TokenType.SEQUENCE || token == TokenType.SEPARATOR || token == TokenType.RETURN || token == TokenType.LAMBDA || token == TokenType.ASYNC || token == TokenType.PARAMETER_TYPE || token == TokenType.GENERIC || token == TokenType.ACTUAL) { expression.bool_values.Add(reader.bool_values.Pop()); } else if (token == TokenType.LITERAL || token == TokenType.TYPEOF || token == TokenType.NAMESPACE || token == TokenType.IMPORT_LIBRARY || token == TokenType.INCLUDE || token == TokenType.USING_NAMESPACE || token == TokenType.INSTANCEOF || token == TokenType.GOTO || token == TokenType.LABEL) { expression.string_values.Add(reader.string_values.Pop()); } else if (token == TokenType.LOOP) { expression.loops.Add(reader.loops.Pop()); } else if (token == TokenType.LOOP_OPERATOR) { expression.bool_values.Add(reader.bool_values.Pop()); expression.string_values.Add(reader.string_values.Pop()); } else if (token == TokenType.OPERATOR) { expression.operators.Add(reader.operators.Pop()); } else if (token == TokenType.VALUE) { expression.byte_values.Add(reader.byte_values.Pop()); expression.values.Add(reader.values.Pop()); } } } reader.tokens.RemoveRange(0, pos); }
/// <summary> /// Parse getted expression /// </summary> public void ParseExpression(TokensReader expr) { bool error = false; int trypos = -1; try { if (expr.tokens.IsEmpty()) { return; } reparse: TokensTemplate template = strongTemplates[expr.tokens[0]]; try { if (template.Parse(expr, exprend)) { List <TokensError> errs = template.Run(); if (!errs.IsEmpty()) { errors.AddRange(errs); error = true; } } else { error = true; } } catch { error = true; } if (error) { if (!tryTokens.IsEmpty()) { LaterCalls.RemoveLast(); if (trypos < 0) { if (tryPositions.IsEmpty()) // TODO: need to change text of error { errors.Add(new InvalidTokensTemplateError(line, "tryPositions is empty")); tryTokens.Clear(); // сделаем это для того, чтобы эта ошибка не повторялась return; // беспричинно и не было исключений (переведите на английский пж) } else { trypos = tryPositions.Pop(); } } expr.tokens.RemoveAt(trypos); if (count == 0) { count = tryCounts.Pop(); } if (count > 0) { count--; expr.tokens.Insert(trypos, tryTokens.Pop()); goto reparse; } } else { errors.Add(new InvalidTokensTemplateError(line, $"Invalid template of token {expression.tokens[0]}")); } } } catch (KeyNotFoundException) { reparse: foreach (TokensTemplate template in flexTemplates) { TokensReader backup = new TokensReader(); backup.Add(expr); try { if (template.Parse(expr, exprend)) { errors.AddRange(template.Run()); return; } else { expr = backup; } } catch { expr = backup; } } if (!tryTokens.IsEmpty()) { LaterCalls.RemoveLast(); if (trypos < 0) { if (tryPositions.IsEmpty()) // TODO: need to change text of error { errors.Add(new InvalidTokensTemplateError(line, "tryPositions is empty")); tryTokens.Clear(); // сделаем это для того, чтобы эта ошибка не повторялась return; // беспричинно и не было исключений (переведите на английский пж) } else { trypos = tryPositions.Pop(); } } expr.tokens.RemoveAt(trypos); if (count == 0) { count = tryCounts.Pop(); } if (count > 0) { count--; expr.tokens.Insert(trypos, tryTokens.Pop()); goto reparse; } } else { errors.Add(new InvalidTokensTemplateError(line, $"Unknown tokens template {string.Join(" ", expr.tokens)}")); } } finally { if (isFuncBody && needLaterCall) { LaterCalls.Call(); } needLaterCall = true; tryTokens.Clear(); } }
public static MethodInfo ParseCallMethod(ref TokensReader expression) { errors = new List <TokensError>(); List <Type> paramTypes = new List <Type>(); TokenType token = expression.tokens.Pop(); if (token == TokenType.LITERAL) { bool mustLiteral = true; StringBuilder parentName = new StringBuilder(); string lastLiteral = ""; while (token == TokenType.LITERAL || token == TokenType.SEPARATOR) { if (mustLiteral && token == TokenType.LITERAL) { lastLiteral = expression.string_values.Pop(); mustLiteral = false; } else if (!mustLiteral && token == TokenType.SEPARATOR) { mustLiteral = true; if (expression.bool_values.Pop()) { parentName.Append(lastLiteral + "."); } else { break; } } else { break; } token = expression.tokens.Pop(); } if (mustLiteral) { return(null); } else { if (parentName.Length == 0) { parentName.Append(lastLiteral); } else { parentName.Length--; // delete last character - '.' } string typename = parentName.ToString(); string methname = lastLiteral; if (token == TokenType.STATEMENT && expression.bool_values.Pop()) // open arguments { token = expression.tokens.Pop(); if (token == TokenType.STATEMENT && !expression.bool_values.Pop()) // empty arguments { CallMethodTemplate callMethod = new CallMethodTemplate(); callMethod.methname = methname; callMethod.paramTypes = paramTypes; callMethod.typename = typename; callMethod.dontPop = true; callMethod.Run(); return(callMethod.method); } else { expression.tokens.Insert(0, token); parse_param: Type paramType = ParseValue(ref expression); if (paramType == null) { return(null); } else { paramTypes.Add(paramType); token = expression.tokens.Pop(); if (token == TokenType.STATEMENT) { if (!expression.bool_values.Pop()) { CallMethodTemplate callMethod = new CallMethodTemplate(); callMethod.methname = methname; callMethod.paramTypes = paramTypes; callMethod.typename = typename; callMethod.dontPop = true; callMethod.Run(); return(callMethod.method); } else { expression.bool_values.Insert(0, true); } } else if (token == TokenType.SEPARATOR && !expression.bool_values.Pop()) { goto parse_param; } else { return(null); } } return(null); } } else { return(null); } } } else { return(null); } }
/// <summary> /// Reads a hash map using an instance of <see cref="TokensReader"/>. /// </summary> /// <param name="reader"></param> /// <returns></returns> public static OpenLispVal ReadHashMap(TokensReader reader) { OpenLispList openLispList = (OpenLispList)ReadList(reader, new OpenLispList(), '{', '}'); return(new OpenLispHashMap(openLispList)); }
public static Type ParseValue(ref TokensReader expression) { Type type = null; TokenType token = expression.tokens.Pop(); if (token == TokenType.VALUE) { byte valtype = expression.byte_values.Pop(); if (valtype == 0) { type = typeof(object); } else if (valtype == 1) { type = typeof(int); } else if (valtype == 2) { type = typeof(string); } else if (valtype == 3) { type = typeof(sbyte); } else if (valtype == 4) { type = typeof(bool); } else if (valtype == 5) { type = typeof(char); } else if (valtype == 6) { type = typeof(float); } else if (valtype == 7) { type = typeof(short); } else if (valtype == 8) { type = typeof(long); } else if (valtype == 9) { type = typeof(double); } LaterCalls.LoadObject(expression.values.Pop()); } else if (token == TokenType.LITERAL) // is method { expression.tokens.Insert(0, TokenType.LITERAL); TokensReader backup = new TokensReader(); backup.Add(expression); MethodInfo method = ParseCallMethod(ref expression); if (method == null) // is local { expression = backup; LocalBuilder local = ParseLocal(ref expression); if (local != null) { LaterCalls.LoadLocal(local); type = local.LocalType; } else // is field { expression = backup; FieldInfo value = ParseField(ref expression); LaterCalls.LoadField(value); type = value.FieldType; } } else { type = method.ReturnType; } } else if (token == TokenType.NEW) { type = ParseNewObject(ref expression); } else if (token == TokenType.STATEMENT) { if (expression.bool_values.Pop()) { type = ParseSmallStatement(ref expression); } else { if (lvlStatement == 0) { errors.Add(new InvalidTokenError(line, $"There are wrong 'closing statement' token")); } else { lvlStatement--; } } } else if (token == TokenType.OPERATOR) { OperatorType op = expression.operators.Pop(); } if (!expression.tokens.IsEmpty() && expression.tokens[0] == TokenType.OPERATOR) { expression.tokens.RemoveAt(0); OperatorType op = expression.operators.Pop(); if (type != null) { if (type == ParseValue(ref expression)) { LaterCalls.LoadOperator(type, op); } else { errors.Add(new InvalidTypeError( line, $"Type {type} before operator {op} not equals type of value after operator")); } } switch (op) { case OperatorType.EQ: case OperatorType.NOTEQ: case OperatorType.NOT: case OperatorType.AND: case OperatorType.OR: case OperatorType.GT: case OperatorType.LT: case OperatorType.GORE: case OperatorType.LORE: case OperatorType.IN: type = typeof(bool); break; case OperatorType.RANGE: break; case OperatorType.POW: type = typeof(float); break; } } return(type); }
/// <summary> /// This static method recursively processes /// OpenLisp.NET forms and tokenizes them. /// </summary> /// <param name="reader"></param> /// <returns></returns> public static OpenLispVal ReadForm(TokensReader reader) { string token = reader.Peek(); if (token == null) { throw new OpenLispContinue(); } OpenLispVal form = null; switch (token) { case "'": reader.Next(); return(new OpenLispList(new OpenLispSymbol("quote"), ReadForm(reader))); case "`": reader.Next(); return(new OpenLispList(new OpenLispSymbol("quasiquote"), ReadForm(reader))); case "~": reader.Next(); return(new OpenLispList(new OpenLispSymbol("unquote"), ReadForm(reader))); case "~@": reader.Next(); return(new OpenLispList(new OpenLispSymbol("splice-unquote"), ReadForm(reader))); case "^": reader.Next(); OpenLispVal meta = ReadForm(reader); return(new OpenLispList(new OpenLispSymbol("with-meta"), ReadForm(reader), meta)); case "@": reader.Next(); return(new OpenLispList(new OpenLispSymbol("deref"), ReadForm(reader))); case "(": form = ReadList(reader, new OpenLispList(), '(', ')'); break; case ")": throw new ParseError("unexpected ')'"); case "[": form = ReadList(reader, new OpenLispVector(), '[', ']'); break; case "]": throw new ParseError("unexpected ']'"); case "{": form = ReadHashMap(reader); break; case "}": throw new ParseError("unexpected '}'"); default: form = ReadAtom(reader); break; } return(form); }
public bool Parse(TokensReader expression, bool expression_end) { if (!expression_end) { return(false); } LaterCalls.Seek(); paramTypes = new List <Type>(); methname = ""; typename = ""; TokenType token = expression.tokens.Pop(); if (token == TokenType.LITERAL) { bool mustLiteral = true; StringBuilder parentName = new StringBuilder(); string lastLiteral = ""; while (token == TokenType.LITERAL || token == TokenType.SEPARATOR) { if (mustLiteral && token == TokenType.LITERAL) { lastLiteral = expression.string_values.Pop(); mustLiteral = false; } else if (!mustLiteral && token == TokenType.SEPARATOR) { mustLiteral = true; if (expression.bool_values.Pop()) { parentName.Append(lastLiteral + "."); } else { break; } } else { break; } token = expression.tokens.Pop(); } if (mustLiteral) { return(false); } else { if (parentName.Length == 0) { parentName.Append(lastLiteral); } else { parentName.Length--; // delete last character - '.' } typename = parentName.ToString(); methname = lastLiteral; if (token == TokenType.STATEMENT && expression.bool_values.Pop()) { if (expression.tokens[0] == TokenType.STATEMENT && !expression.bool_values[0]) { if (expression.tokens.Count == 1) { return(true); } else { return(false); } } else { parse_param: Type paramType = PartTemplate.ParseValue(ref expression); if (paramType == null) { return(false); } else { paramTypes.Add(paramType); token = expression.tokens.Pop(); if (token == TokenType.STATEMENT) { if (!expression.bool_values.Pop()) { if (expression.tokens.Count == 0) { return(true); } else { return(false); } } else { expression.bool_values.Insert(0, true); } } else if (token == TokenType.SEPARATOR && !expression.bool_values.Pop()) { goto parse_param; } else { return(false); } } return(false); } } else { return(false); } } } else { return(false); } }