@@ -159,6 +159,22 @@ private static void fillArithOps() {
159159 }
160160 }
161161
162+ /*
163+ * Allow the directory catenation operator (/) to take file operands as
164+ * well as strings: a file contributes its filename. The result is
165+ * always a string. The frontend replaces each file operand with its
166+ * filename future, so the underlying DIRCAT op still sees only strings.
167+ */
168+ OpInputType dircatFile = new OpInputType (Types .F_FILE , false );
169+ OpInputType dircatString = new OpInputType (Types .F_STRING , false );
170+ for (List <OpInputType > dircatArgs :
171+ Arrays .asList (Arrays .asList (dircatFile , dircatString ),
172+ Arrays .asList (dircatString , dircatFile ),
173+ Arrays .asList (dircatFile , dircatFile ))) {
174+ registerOverload (ExMParser .DIV , BuiltinOpcode .DIRCAT ,
175+ new OpType (Types .F_STRING , dircatArgs ));
176+ }
177+
162178 Type sprintfArg = UnionType .createUnionType (Types .F_STRING , Types .F_INT , Types .F_FLOAT , Types .F_BOOL );
163179 List <OpInputType > sprintfArgs = Arrays .asList (new OpInputType (Types .F_STRING , false ),
164180 new OpInputType (sprintfArg , true ));
@@ -176,6 +192,15 @@ private static void registerOperator(int token, BuiltinOpcode opCode,
176192 arithOps .put (token , new Op (opCode , opType ));
177193 }
178194
195+ /**
196+ * Register an extra overload for an operator, leaving the canonical type
197+ * recorded for the opcode alone.
198+ */
199+ private static void registerOverload (int token , BuiltinOpcode opCode ,
200+ OpType opType ) {
201+ arithOps .put (token , new Op (opCode , opType ));
202+ }
203+
179204 private static String getOpTypeName (PrimType numType ) {
180205 switch (numType ) {
181206 case BOOL :
0 commit comments