jokinen@tucos.UUCP (Matti Jokinen) (05/17/88)
Description: If one or more tags are missing in a tagcase statement and there is no others-arm, the compiler reports the error but does not list the missing tags. It is often rather tedious to find out which tags are missing. Repeat-by: Run the following shell script: cat > main.clu << 'EOF' start_up = proc() t = oneof[a,b: null] x: t := t$make_a(nil) tagcase x tag a: end end start_up EOF clu main Fix: The error message comes from the procedure c_tagcase in the file ~CLU/cmp/cstmt2.clu. Replace it with the following code: c_tagcase = proc (e: c_env, ts: tagstmt) at: typespec := c_expr(e, ts.obj) specs: fieldspeclist := c_oneof_specs(e, at) except when abstract: c_tag_sugar(e, at, ts) return end used: flaglist := c_tagarms(e, ts.arms, specs) tagcase ts.others_ tag body (mb: body): all_used: bool for all_used in flaglist$elements(used) do if ~all_used then break end end if all_used cand ~fieldspeclist$empty(specs) then c_env$err1(e, "others arm not allowed - all selectors present") end c_body(e, mb) tag none: miss: as := as$new() for i: int in fieldspeclist$indexes(specs) do if ~ used[i] then as$addh(miss, specs[i].sel) end end count: int := as$size(miss) if count > 0 then message: as := as$["others arm required - ", int$unparse(count), " ", "selectors", " missing: "] if count = 1 then message[4] := "selector" end for i: int in as$indexes(miss) do if i > 1 then as$addh(message, ", ") end as$addh(message,miss[i]) end c_env$err(e, qs$a2s(message)) end end end c_tagcase If you want long lists to be folded on more than one line, replace the procedure cenv$output in ~CLU/cmp/cenv.clu with the following routine pair: output = proc (e: rep, msg: qs) st: stream := e.errst l: int := e.line begin if l > 0 then stream$puts(st, int$unparse(e.line)) stream$putc(st, ':') end for s: str in lines(msg) do stream$putc(st, '\t') stream$putl(st, s) end end except others: end end output lines = iter(msg: qs) yields(str) maxlength = 72 s: str := "" for t: str in qs$elements(msg) do s := s || t while str$size(s) > maxlength do i: int := maxlength while true do if s[i+1] = ' ' then yield(str$substr(s,1,i)) s := str$rest(s,i+2) break elseif s[i] = ',' then yield(str$substr(s,1,i)) s := str$rest(s,i+1) break else i := i - 1 end end except when bounds: yield(string$substr(s,1,maxlength)) s := string$rest(s,maxlength+1) end end end yield(s) end lines