private bool ParseNewExpression(ref ASTNode retn) { if (tokenStream.Current != ExpressionTokenType.New) { return(false); } tokenStream.Save(); tokenStream.Advance(); TypeLookup typeLookup = new TypeLookup(); // todo -- allocates a list :( bool valid = ParseTypePath(ref typeLookup); if (!valid || tokenStream.Current != ExpressionTokenType.ParenOpen) { typeLookup.Release(); tokenStream.Restore(); return(false); } LightList <ASTNode> parameters = null; if (!ParseListExpression(ref parameters, ExpressionTokenType.ParenOpen, ExpressionTokenType.ParenClose)) { Abort(); } retn = ASTNode.NewExpressionNode(typeLookup, parameters); return(true); }
public bool ParseTypePath(ref TypeLookup retn) { if (tokenStream.Current != ExpressionTokenType.Identifier) { return(false); } tokenStream.Save(); if (!ParseTypePathHead(ref retn)) { tokenStream.Restore(); retn.Release(); return(false); } if (!tokenStream.HasMoreTokens) { return(true); } if (tokenStream.Current == ExpressionTokenType.LessThan && !ParseTypePathGenerics(ref retn)) { tokenStream.Restore(); retn.Release(); return(false); } if (tokenStream.Current == ExpressionTokenType.ArrayAccessOpen && tokenStream.HasMoreTokens && tokenStream.Next == ExpressionTokenType.ArrayAccessClose) { retn.isArray = true; tokenStream.Advance(2); } return(true); }
public override void Release() { if (parameters != null) { for (int i = 0; i < parameters.Count; i++) { parameters[i].Release(); } } typeLookup.Release(); LightList <ASTNode> .Release(ref parameters); s_NewExpressionNodePool.Release(this); }
// todo -- modifier list public override void Release() { base.Release(); returnTypeLookup.Release(); body?.Release(); if (signatureList == null) { return; } for (int i = 0; i < signatureList.Length; i++) { signatureList[i].type?.Release(); } }
private bool ParseTypePathGenericStep(ref TypeLookup retn) { TypeLookup arg = default; while (tokenStream.HasMoreTokens) { if (tokenStream.Current == ExpressionTokenType.Identifier) { if (!ParseTypePathHead(ref arg)) { tokenStream.Restore(); return(false); } arg.generics = null; continue; } if (tokenStream.Current == ExpressionTokenType.Comma) { retn.generics = retn.generics ?? StructList <TypeLookup> .GetMinSize(4); retn.generics.Add(arg); tokenStream.Advance(); continue; } if (tokenStream.Current == ExpressionTokenType.LessThan) { if (ParseTypePathGenerics(ref arg)) { continue; } } tokenStream.Restore(); retn.Release(); return(false); } retn.generics = retn.generics ?? StructList <TypeLookup> .GetMinSize(4); retn.generics.Add(arg); return(true); }
private bool ParseTypePathHead(ref TypeLookup retn) { if (tokenStream.Current != ExpressionTokenType.Identifier) { return(false); } string identifier = tokenStream.Current.value; tokenStream.Save(); tokenStream.Advance(); string lastString = identifier; while (tokenStream.Current == ExpressionTokenType.Dot) { tokenStream.Advance(); if (tokenStream.Current != ExpressionTokenType.Identifier) { retn.Release(); retn = default; tokenStream.Restore(); break; } s_StringBuilder.Append(lastString); s_StringBuilder.Append("."); lastString = tokenStream.Current.value; tokenStream.Advance(); } if (s_StringBuilder.Length > 1) { s_StringBuilder.Remove(s_StringBuilder.Length - 1, 1); } retn.namespaceName = s_StringBuilder.ToString(); retn.typeName = lastString; s_StringBuilder.Clear(); return(true); }
// (int)something private bool ParseDirectCastExpression(ref ASTNode retn) { if (tokenStream.Current != ExpressionTokenType.ParenOpen) { return(false); } ASTNode expression = null; int advance = tokenStream.FindMatchingIndex(ExpressionTokenType.ParenOpen, ExpressionTokenType.ParenClose); if (advance == -1) { Abort(); return(false); } tokenStream.Save(); ExpressionParser subParser = CreateSubParser(advance); TypeLookup typeLookup = new TypeLookup(); bool valid = subParser.ParseTypePath(ref typeLookup); subParser.Release(); if (!valid) { tokenStream.Restore(); return(false); } if (!ParseExpression(ref expression)) { typeLookup.Release(); tokenStream.Restore(); tokenStream.Restore(); return(false); } retn = ASTNode.DirectCastNode(typeLookup, expression); return(true); }
private bool ParseAttribute(ref AttributeNode node) { if (tokenStream.Current != ExpressionTokenType.ArrayAccessOpen) { return(false); } tokenStream.Save(); tokenStream.Advance(); TypeLookup typeLookup = default; ExpressionParser parser = new ExpressionParser(tokenStream); if (!parser.ParseTypePath(ref typeLookup)) { goto fail; } tokenStream.Set(parser.GetTokenPosition()); parser.Release(false); if (tokenStream.Current == ExpressionTokenType.ArrayAccessClose) { tokenStream.Advance(); node = new AttributeNode() { typeLookup = typeLookup }; return(true); } fail: { typeLookup.Release(); parser.Release(false); return(false); } }
public override void Release() { typeLookup.Release(); value?.Release(); }
public override void Release() { base.Release(); typeLookup.Release(); }
private bool ParseDeclaration(ref ASTNode node) { AttributeNode attrNode = null; LightList <AttributeNode> attributes = LightList <AttributeNode> .Get(); while (ParseAttribute(ref attrNode)) { attributes.Add(attrNode); if (tokenStream.Current != ExpressionTokenType.ArrayAccessOpen) { break; } } if (attributes.size == 0) { LightList <AttributeNode> .Release(ref attributes); } if (tokenStream.Current != ExpressionTokenType.Identifier) { return(false); } // modifiers? -> returnType -> name -> signature -> openBrace * closeBrace tokenStream.Save(); bool isStatic = false; if (tokenStream.Current == "static") { isStatic = true; tokenStream.Advance(); } ExpressionParser parser = new ExpressionParser(tokenStream); StructList <LambdaArgument> signature = null; TypeLookup typeLookup = default; if (!parser.ParseTypePath(ref typeLookup)) { goto fail; } tokenStream.Set(parser.GetTokenPosition()); parser.Release(false); if (tokenStream.Current != ExpressionTokenType.Identifier) { goto fail; } string name = tokenStream.Current.value; tokenStream.Advance(); // if semi colon then we have a field! if (tokenStream.Current == ExpressionTokenType.SemiColon) { tokenStream.Advance(); node = new FieldNode() { name = name, isStatic = isStatic, attributes = attributes, typeLookup = typeLookup }; return(true); } if (tokenStream.Current != ExpressionTokenType.ParenOpen) { goto fail; } signature = StructList <LambdaArgument> .Get(); if (tokenStream.NextTokenIs(ExpressionTokenType.ParenClose)) { tokenStream.Advance(2); } else { int matchingIndex = tokenStream.FindMatchingIndex(ExpressionTokenType.ParenOpen, ExpressionTokenType.ParenClose); if (matchingIndex == -1) { goto fail; } TokenStream subStream = tokenStream.AdvanceAndReturnSubStream(matchingIndex); subStream.Advance(); tokenStream.Advance(); if (!ExpressionParser.ParseSignature(subStream, signature)) { goto fail; } for (int i = 0; i < signature.size; i++) { if (signature.array[i].type == null) { throw new ParseException($"When defining a method you must specify a type for all arguments. Found identifier {signature.array[i].identifier} but no type was given."); } } } if (tokenStream.Current != ExpressionTokenType.ExpressionOpen) { goto fail; } BlockNode block = ParseBlock(); node = new MethodNode() { body = block, returnTypeLookup = typeLookup, attributes = attributes, name = name, isStatic = isStatic, signatureList = signature != null?signature.ToArray() : s_EmptySignature }; StructList <LambdaArgument> .Release(ref signature); parser.Release(false); return(true); fail: { tokenStream.Restore(); parser.Release(false); typeLookup.Release(); signature?.Release(); return(false); } }
private bool ParseLocalVariableDeclaration(ref ASTNode node) { ExpressionParser parser = default; TypeLookup typeLookup = default; if (tokenStream.Current == ExpressionTokenType.Var) { if (!tokenStream.NextTokenIs(ExpressionTokenType.Identifier)) { return(false); } tokenStream.Advance(); } else if (tokenStream.Current == ExpressionTokenType.Identifier) { tokenStream.Save(); parser = new ExpressionParser(tokenStream); if (!parser.ParseTypePath(ref typeLookup)) { goto fail; } tokenStream.Set(parser.GetTokenPosition()); parser.Release(false); } else { goto fail; } if (tokenStream.Current != ExpressionTokenType.Identifier) { goto fail; } string name = tokenStream.Current.value; tokenStream.Advance(); if (tokenStream.Current == ExpressionTokenType.SemiColon) { tokenStream.Advance(); node = new LocalVariableNode() { name = name, typeLookup = typeLookup // will be default for var }; return(true); } if (tokenStream.Current == ExpressionTokenType.Assign) { // todo -- would fail on this: var x = new F(() => { return x; }); tokenStream.Advance(); ASTNode expression = null; if (!ParseTerminatedExpression(ref expression)) { goto fail; } node = new LocalVariableNode() { name = name, value = expression, typeLookup = typeLookup // will be default for var }; return(true); } fail: { parser.Release(false); typeLookup.Release(); tokenStream.Restore(); return(false); } }
public override void Release() { s_TypeNodePool.Release(this); typeLookup.Release(); }
public override void Release() { typeLookup.Release(); expression?.Release(); s_UnaryNodePool.Release(this); }
public override void Release() { genericPath.Release(); s_GenericTypePathNode.Release(this); }