private TCExplicitFunctionDefinition getPostDefinition() { TCPatternList last = new TCPatternList(); int psize = paramPatternList.size(); for (TCPattern p : paramPatternList.get(psize - 1)) { last.add(p); } last.add(new TCIdentifierPattern(name.getResultName(location))); TCPatternListList parameters = new TCPatternListList(); if (psize > 1) { parameters.addAll(paramPatternList.subList(0, psize - 1)); } parameters.add(last); TCExplicitFunctionDefinition def = new TCExplicitFunctionDefinition( accessSpecifier, name.getPostName(postcondition.location), typeParams, type.getCurriedPostType(isCurried), parameters, postcondition, null, null, false, null); def.classDefinition = classDefinition; return def; }
@Override public void typeResolve(Environment base) { if (typeParams != null) { FlatCheckedEnvironment params = new FlatCheckedEnvironment(getTypeParamDefinitions(), base, NameScope.NAMES); type = type.typeResolve(params, null); } else { type = type.typeResolve(base, null); } if (base.isVDMPP()) { name.setTypeQualifier(type.parameters); } if (body instanceof TCSubclassResponsibilityExpression || body instanceof TCNotYetSpecifiedExpression) { isUndefined = true; } if (precondition != null) { predef.typeResolve(base); } if (postcondition != null) { postdef.typeResolve(base); } for (TCPatternList pp : paramPatternList) { pp.typeResolve(base); } }
private TCType checkParams(ListIterator<TCPatternList> plists, TCFunctionType ftype) { TCTypeList ptypes = ftype.parameters; TCPatternList patterns = plists.next(); if (patterns.size() > ptypes.size()) { report(3020, "Too many parameter patterns"); detail2("Pattern(s)", patterns, "Type(s)", ptypes); return ftype.result; } else if (patterns.size() < ptypes.size()) { report(3021, "Too few parameter patterns"); detail2("Pattern(s)", patterns, "Type(s)", ptypes); return ftype.result; } if (ftype.result instanceof TCFunctionType) { if (!plists.hasNext()) { // We're returning the function itself return ftype.result; } // We're returning what the function returns, assuming we // pass the right parameters. Note that this recursion // means that we finally return the result of calling the // function with *all* of the curried argument sets applied. // This is because the type check of the body determines // the return type when all of the curried parameters are // provided. return checkParams(plists, (TCFunctionType) ftype.result); } if (plists.hasNext()) { report(3022, "Too many curried parameters"); } return ftype.result; }
private TCDefinitionListList getParamDefinitions() { TCDefinitionListList defList = new TCDefinitionListList(); TCFunctionType ftype = type; // Start with the overall function Iterator<TCPatternList> piter = paramPatternList.iterator(); while (piter.hasNext()) { TCPatternList plist = piter.next(); TCDefinitionList defs = new TCDefinitionList(); TCTypeList ptypes = ftype.parameters; Iterator<TCType> titer = ptypes.iterator(); if (plist.size() != ptypes.size()) { // This is a type/param mismatch, reported elsewhere. But we // have to create definitions to avoid a cascade of errors. TCType unknown = new TCUnknownType(location); for (TCPattern p : plist) { defs.addAll(p.getDefinitions(unknown, NameScope.LOCAL)); } } else { for (TCPattern p : plist) { defs.addAll(p.getDefinitions(titer.next(), NameScope.LOCAL)); } } defList.add(checkDuplicatePatterns(defs)); if (ftype.result instanceof TCFunctionType) // else??? { ftype = (TCFunctionType) ftype.result; } } return defList; }