#
# KEHOME/src/nvlist.icn
# Aug/26/2005
# see grammar in symbol.icn
# NOTE: for convenience, question.icn calls nv2nov for
# qphrase,wphrase,bphrase,partphrase
#
# subject is object;
# subject has nvobject;
# subject haspart nvobject;
# subject do nvobject pplist done;
# subject rel object pplist;
#
# subject ::= phraselist; # SYMBOL("subject", phraselist)
# object ::= phraselist; # SYMBOL("object", phraselist)
# nvobject ::= nvlist; # SYMBOL("nvobject",nvlist)
#
# phraselist ::= list(phrase,",");
# phrase ::= PHRASE([word,...]);
#
# nvlist ::= list(nvphrase,",");
# nvphrase ::=
# NVPHRASE("nv",[name,op,value])
# NVPHRASE("nvnull",[name])
# PHRASE([...])
#
# novlist ::=
# [name,op,value]
# [name]
# op ::=
# "="
# "+="
# "-="
# "*="
record NVPHRASE (
novtype, # "nv" | "nvnull"
novlist # list
##nvname, # string
##nvop, # string (can be "")
##nvvalue # record or string or ... (can be "")
)
# methods
# new_nv(novlist)
# nv_name(x)
# nv_op(x)
# nv_value(x)
# nv_novlist(x)
# nv_badtype(t,x,ierror) # error message
# nv_writes(fd,x)
# nv_unparse(x)
# nv_tsize(tsym)
# nv_map_symbol(x,tok))
# nv2nov(nvphrase)
# nov2nv(novlist)
# symbol2nv(symbol)
# string
procedure nv_name(x)
#===================
local t,nt
static ierror
initial ierror := "Internal ERROR: nv_name: "
case t := type(x) of {
"NVPHRASE": { }
default: { return nv_badtype(t,x,ierror) }
}
case nt := x.novtype of {
default: { return nv_badtype(nt,x,ierror) }
"nv": { return x.novlist[1] }
"nvnull": { return x.novlist[1] }
}
end
procedure nv_op(x)
#=================
local t,nt
static ierror
initial ierror := "Internal ERROR: nv_op: "
case t := type(x) of {
"NVPHRASE": { }
default: { return nv_badtype(t,x,ierror) }
}
case nt := x.novtype of {
default: { return nv_badtype(nt,x,ierror) }
"nv": { return x.novlist[2] }
"nvnull": { return NVSEPARATOR }
}
end
procedure nv_value(x)
#====================
local t,nt
static ierror
initial ierror := "Internal ERROR: nv_value: "
case t := type(x) of {
"NVPHRASE": { }
default: { return nv_badtype(t,x,ierror) }
}
case nt := x.novtype of {
default: { return nv_badtype(nt,x,ierror) }
"nv": { return x.novlist[3] }
"nvnull": { return &null }
}
end
# string
procedure nv_badtype(t,x,ierror)
#===============================
local head
head := "UnexpectedType("||t||") "
writes_type(myerr,x,ierror||head||"x")
writes_type(mylog,x,ierror||head||"x")
return "(("||unparse(x)||"))"
end
procedure new_nv(novlist)
#========================
local t
static ierror
initial {
ierror := "Internal ERROR: new_nv: "
}
case t := type(novlist) of {
"list": { }
default: {
writes_type(myerr,novlist,ierror||"not a list: novlist")
writes_type(mylog,novlist,ierror||"not a list: novlist")
#fail
novlist := [novlist] # enclose in list
}
} # end case t
case *novlist of {
3: { return NVPHRASE("nv",novlist) }
1: { return NVPHRASE("nvnull",novlist) }
default: {
writes_type(myerr,novlist,ierror||"wrong size: novlist")
writes_type(mylog,novlist,ierror||"wrong size: novlist")
#fail
return NVPHRASE("nv",novlist)
}
} # end case *novlist
end
procedure nv_writes(fd,x)
#========================
local t
static ierror
initial {
ierror := "Internal ERROR: nv_writes: "
}
case t := type(x) of {
"NVPHRASE": { }
"null": {
if DEBUG=="NULL" then {
writes_type(mybug,x,ierror||"null: x")
writes_type(mylog,x,ierror||"null: x")
}
fail
}
default: {
writes_type(myerr,x,ierror||"unexpected type: x")
writes_type(mylog,x,ierror||"unexpected type: x")
fail
}
} # end case t
writes(fd,"NVPHRASE(")
writes(fd,x.novtype,",")
writes_any(fd,x.novlist)
writes(fd,")")
end
# string
procedure nv_unparse(x)
#======================
# x ::= NVPHRASE
local novtype,novlist,line
static lsep,psep
initial {
lsep := ","
psep := PSEPARATOR # " "
}
case x.novtype of {
"nv": {
line := unparse(x.novlist[1],psep,psep)
line ||:= psep||unparse(x.novlist[2],psep,psep)
line ||:= psep||unparse(x.novlist[3],psep,psep)
return line
}
"nvnull": { return unparse(x.novlist[1],psep,psep) }
}
end
# integer
procedure nv_tsize(tsym)
#=======================
# tsym ::= NVPHRASE
return tsize(tsym.novlist)
end
# NVPHRASE
procedure nv_map_symbol(x,tok)
#=============================
return new_nv(map_symbol(x.novlist,tok))
end
# list
procedure nv_novlist(x)
#======================
return x.novlist
end
# novlist or list of novlist
procedure nv2nov(nvphrase)
#=========================
# called by set_charnest() in char.icn
# called by qsubject() in question.icn
# called by qverb() in question.icn
# called by qobject() in question.icn
# called by qvalue() in question.icn
local t,st,nov
static ierror,warning,utype,ustype
initial {
ierror := "Internal ERROR: nv2nov: "
warning := "WARNING: nv2nov: "
utype := warning||"unexpected type: nvphrase"
ustype := ierror||"unexpected stype: nvphrase"
}
nov := []
case t := type(nvphrase) of {
"NVPHRASE": { nov := nv_novlist(nvphrase) }
"PHRASE": { nov := [phrase_unparse(nvphrase)] }
"BSE": {
nov := bse_list(nvphrase)
}
"SYMBOL": {
case st := nvphrase.stype of {
"nvobject": { # SYMBOL("nvobject",nvlist)
nov := nv2nov(nvphrase.svalue)
}
default: {
writes_type(myerr,nvphrase,ustype)
writes_type(mylog,nvphrase,ustype)
nov := [nvphrase]
}
} # end case st
} # end "SYMBOL"
"list": { # novlist or nvlist
case *nvphrase of {
0: {
if DEBUG==("NULL"|"EMPTY"|"LIST") then {
writes_type(mybug,nvphrase,utype)
writes_type(mylog,nvphrase,utype)
}
}
default: {
#####writes_type(myerr,nvphrase,utype)
#####writes_type(mylog,nvphrase,utype)
}
} # end case *nvphrase
nov := []
every put(nov,nv2nov(!nvphrase))
} # end "list"
"string": {
case nvphrase of {
"?": {
# get lots of "?"
}
default: {
writes_type(myerr,nvphrase,utype)
writes_type(mylog,nvphrase,utype)
}
}
nov := [nvphrase]
}
default: {
writes_type(myerr,nvphrase,utype)
writes_type(mylog,nvphrase,utype)
nov := [nvphrase]
}
}
return nov
end
# NVPHRASE
procedure nov2nv(novlist)
#========================
local nv
static ierror,utype,usize
initial {
ierror := "Internal ERROR: nov2nv: "
utype := ierror||"unexpected type: novlist"
usize := ierror||"unexpected size: novlist"
}
return new_nv(novlist)
end
#======================================================#
# list
procedure symbol2nov(symbol)
#===========================
# called by set_charnest() in char.icn
# called by do_action() in action.icn
# output ::=
# [name]
# [name,op,value]
local nvnest
static info,ierror
initial {
info := "INFO: symbol2nov: "
ierror := "Internal ERROR: symbol2nov: "
}
if DEBUG==("ACTION"|"EVENT") then {
writes_type(mybug,symbol,info||"symbol")
writes_type(mylog,symbol,info||"symbol")
}
nvnest := []
case type(symbol) of {
default: {
writes_type(myerr,symbol,ierror||"unexpected type: symbol")
writes_type(mylog,symbol,ierror||"unexpected type: symbol")
fail
}
"list": { every put(nvnest,symbol2nov(!symbol)) }
"set": { every put(nvnest,symbol2nov(!symbol)) }
("string"|"integer"|"real"): {
nvnest := [string(symbol)]
}
"SYMBOL": { nvnest := nv2nov(symbol) }
"NVPHRASE": { nvnest := nv2nov(symbol) }
} # end case type
if DEBUG==("ACTION"|"EVENT") then {
writes_type(mybug,nvnest,info||"nvnest")
writes_type(mylog,nvnest,info||"nvnest")
}
return nvnest
end
#