public static LinkedListNode<Lexeme> TryParse(LinkedListNode<Lexeme> lexemes, out Node resultNode) { resultNode = null; var nextLexeme = StructDecl.TryParse(lexemes, out StructDecl structDecl); if (structDecl != null) { resultNode = structDecl; return nextLexeme; } nextLexeme = FnDecl.TryParse(lexemes, out FnDecl fn); if (fn != null) { resultNode = fn; return nextLexeme; } nextLexeme = Stmt.TryParseStruct(lexemes, out Stmt stmt); if (stmt != null) { resultNode = stmt; return nextLexeme; } return lexemes; }
public override void ResolveNames(Scope scope, ErrorHandler errorHandler) { Value?.ResolveNames(scope, errorHandler); FnDecl target = scope.FindFn(); if (target == null) { errorHandler.AddMessage(Severity.Error, $"return statement is not inside a function", Token); } TargetFn = target; }
public override void CheckTypes(ErrorHandler errorHandler) { if (TargetNode != null) { return; } var viableCandidates = new List <FnDecl>(); var args = Args.ToList(); foreach (var decl in TargetNodeCandidates) { var parameters = decl.Parameters.ToList(); if (parameters.Count != args.Count) { continue; } bool success = false; for (int i = 0; i < parameters.Count; i++) { if (!args[i].CanConvertTo(parameters[i].Type, errorHandler)) { break; } success = true; } if (!success) { continue; } viableCandidates.Add(decl); } if (viableCandidates.Count == 0) { errorHandler.AddMessage(Severity.Error, $"No overload of function {Token.Value} with matching parameters found", Token); } else if (viableCandidates.Count > 1) { errorHandler.AddMessage(Severity.Error, $"Multiple overloads of function {Token.Value} with the same parameter types found", Token); } else { TargetNode = viableCandidates[0]; } }
public static LinkedListNode <Lexeme> TryParse(LinkedListNode <Lexeme> lexemes, out FnDecl resultNode) { resultNode = null; var nextLexeme = Type.TryParse(lexemes, out Type type); if (type == null) { return(lexemes); } if (nextLexeme.Value.Type != LT.IDENT) { return(lexemes); } Lexeme token = nextLexeme.Value; nextLexeme = nextLexeme.Next; if (nextLexeme.Value.Type != LT.OP_PAREN_O) { return(lexemes); } nextLexeme = nextLexeme.Next; List <FnParam> fnParams = new List <FnParam>(); nextLexeme = FnParam.TryParse(nextLexeme, out FnParam arg); if (arg != null) { fnParams.Add(arg); while (nextLexeme.Value.Type == LT.OP_COMMA) { nextLexeme = nextLexeme.Next; nextLexeme = FnParam.TryParse(nextLexeme, out arg); if (arg == null) { throw new Exception($"Trailing comma in argument list at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } fnParams.Add(arg); } } if (nextLexeme.Value.Type != LT.OP_PAREN_C) { throw new Exception($"Missing closing parenthesis in function definition at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } nextLexeme = nextLexeme.Next; if (nextLexeme.Value.Type != LT.OP_BRACE_O) { throw new Exception($"Cannot find function body opening brace at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } nextLexeme = nextLexeme.Next; List <Stmt> stmts = new List <Stmt>(); nextLexeme = Stmt.TryParse(nextLexeme, out Stmt stmt); while (stmt != null) { stmts.Add(stmt); nextLexeme = Stmt.TryParse(nextLexeme, out stmt); } if (nextLexeme.Value.Type != LT.OP_BRACE_C) { throw new Exception($"Missing closing brace for function body at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } nextLexeme = nextLexeme.Next; resultNode = new FnDecl { Type = type, Parameters = fnParams, Body = new BlockBody(stmts), Token = token }; return(nextLexeme); }