protected override bool Visit(ASTLambda node) { _procedureStack.Push(node); _scope = new Scope { Parent = _scope }; var arguments = new List <ProcedureType.Argument>(node.Arguments.Count()); foreach (var arg in node.Arguments) { if (!Visit(arg)) { _procedureStack.Pop(); return(false); } if (!(arg.TypeInfo is TypeType c) || c.Type.Equals(Cache.GetUnknown())) { Error(arg.Position, "Argument did not specify a valid type."); return(false); } _scope.TryAddSymbol(arg.Name, c.Type); arguments.Add(new ProcedureType.Argument(arg.Name, c.Type)); } var ret = node.Return; if (ret == null) { node.TypeInfo = new ProcedureType(arguments, Cache.GetVoid()); } else if (Visit(ret)) { if (!(ret.TypeInfo is TypeType c) || c.Type.Equals(Cache.GetUnknown())) { Error(ret.Position, "Return was not specified as a valid type."); return(false); } node.TypeInfo = new ProcedureType(arguments, c.Type); } else { _procedureStack.Pop(); return(false); } if (!Visit(node.Block)) { _procedureStack.Pop(); return(false); } _scope = _scope.Parent; _procedureStack.Pop(); return(true); }
protected override bool Visit(ASTLambda node) { if (!Visit(node.Block)) { return(false); } // This should be safe, if we did typechecking correct var type = (ProcedureType)node.TypeInfo; var arguments = node.Arguments.Select(arg => new CFunction.Argument { Name = arg.Name, Type = GetCType(arg.TypeInfo) }); _lastNode = new CFunction { Name = $"{LambdaName}{_lambdaId++}", Arguments = arguments, Return = GetCType(type.Return), Block = (CBlock)_lastNode // Should be safe }; return(true); }
protected abstract bool Visit(ASTLambda node);