github.com/archlabjp/eeslism-go@v0.0.0-20231109122333-4bb7bfcdf292/eeslism/escntldat.go (about) 1 //This file is part of EESLISM. 2 // 3 //Foobar is free software : you can redistribute itand /or modify 4 //it under the terms of the GNU General Public License as published by 5 //the Free Software Foundation, either version 3 of the License, or 6 //(at your option) any later version. 7 // 8 //Foobar is distributed in the hope that it will be useful, 9 //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the 11 //GNU General Public License for more details. 12 // 13 //You should have received a copy of the GNU General Public License 14 //along with Foobar.If not, see < https://www.gnu.org/licenses/>. 15 16 /* esccntldat.c */ 17 18 package eeslism 19 20 import ( 21 "errors" 22 "fmt" 23 "strconv" 24 "strings" 25 ) 26 27 /* 制御、スケジュール設定式の入力 */ 28 29 // char Hload, /* Hload = HEATING_LOAD */ 30 // Cload, /* Cload = COOLING_LOAD */ 31 // HCload; /* HCload = HEATCOOL_LOAD */ 32 33 func Contrldata(fi *EeTokens, Ct *[]*CONTL, Ci *[]*CTLIF, 34 Cs *[]*CTLST, 35 Simc *SIMCONTL, Compnt []*COMPNT, 36 Mpath []*MPATH, Wd *WDAT, Exsf *EXSFS, Schdl *SCHDL) { 37 //loadcmp, cmp := (*COMPNT)(nil), (*COMPNT)(nil) 38 // varcontl, Contl, ctl := (*CONTL)(nil), (*CONTL)(nil), (*CONTL)(nil) 39 // ctlif, Ctlif, cti := (*CTLIF)(nil), (*CTLIF)(nil), (*CTLIF)(nil) 40 // ctlst, Ctlst, cts := (*CTLST)(nil), (*CTLST)(nil), (*CTLST)(nil) 41 vptr, vpath := VPTR{}, VPTR{} 42 var load *ControlSWType 43 i := 0 44 Nm := 0 45 var loadcmp *COMPNT = nil 46 Hload := HEATING_LOAD 47 Cload := COOLING_LOAD 48 HCload := HEATCOOL_LOAD 49 50 *Ct = make([]*CONTL, 0) 51 *Cs = make([]*CTLST, 0) 52 *Ci = make([]*CTLIF, Nm) 53 54 load = nil 55 for fi.IsEnd() == false { 56 s := fi.GetToken() 57 if s == "\n" { 58 continue 59 } 60 if len(s) == 0 || s[0] == '*' { 61 break 62 } 63 64 load = nil 65 VPTRinit(&vptr) 66 VPTRinit(&vpath) 67 68 Contl := NewCONTL() 69 Contl.Type = ' ' 70 Contl.Cst = NewCTLST() 71 72 flag_ignore := false 73 for fi.IsEnd() == false { 74 if s == "if" { 75 Ctlif := NewCTLIF() 76 Contl.Type = 'c' 77 Contl.Cif = Ctlif 78 s = strings.Trim(fi.GetToken(), "()") 79 ctifdecode(s, Ctlif, Simc, Compnt, Mpath, Wd, Exsf, Schdl) 80 *Ci = append(*Ci, Ctlif) 81 } else if s == "AND" { 82 Ctlif := NewCTLIF() 83 Contl.Type = 'c' 84 if Contl.AndCif == nil { 85 Contl.AndCif = Ctlif 86 } else { 87 Contl.AndAndCif = Ctlif 88 } 89 s = strings.Trim(fi.GetToken(), "()") 90 ctifdecode(s, Ctlif, Simc, Compnt, Mpath, Wd, Exsf, Schdl) 91 *Ci = append(*Ci, Ctlif) 92 } else if s == "OR" { 93 Ctlif := NewCTLIF() 94 Contl.Type = 'c' 95 Contl.OrCif = Ctlif 96 s = strings.Trim(fi.GetToken(), "()") 97 ctifdecode(s, Ctlif, Simc, Compnt, Mpath, Wd, Exsf, Schdl) 98 *Ci = append(*Ci, Ctlif) 99 } else if strings.HasPrefix(s, "LOAD") { 100 loadcmp = nil 101 if strings.ContainsRune(s, ':') { 102 if len(s) == 5 && ControlSWType(s[5]) == HEATING_LOAD { 103 load = new(ControlSWType) 104 *load = Hload 105 } else if len(s) == 5 && ControlSWType(s[5]) == COOLING_LOAD { 106 load = new(ControlSWType) 107 *load = Cload 108 } else { 109 var iderr error 110 i, iderr = idscw(s[5:], Schdl.Scw, "") 111 if iderr == nil { 112 load = &Schdl.Isw[i] 113 } else { 114 Eprint("<Contrldata>", s) 115 } 116 } 117 } else { 118 load = &HCload 119 } 120 } else if s == "-e" { 121 s = fi.GetToken() 122 for _, cmp := range Compnt { 123 if s == cmp.Name { 124 loadcmp = cmp 125 } 126 } 127 } else if st := strings.IndexRune(s, '='); st != -1 { 128 ss := strings.SplitN(s, "=", 2) 129 key, value := ss[0], ss[1] 130 var err error 131 if load != nil { 132 vptr, err = loadptr(loadcmp, load, key, Compnt) 133 load = nil 134 } else { 135 vptr, vpath, err = ctlvptr(key, Simc, Compnt, Mpath, Wd, Exsf, Schdl) 136 } 137 if err == nil { 138 Ctlst := Contl.Cst 139 Ctlst.Type = vptr.Type 140 Ctlst.PathType = vpath.Type 141 Ctlst.Path = vpath.Ptr 142 if Ctlst.Type == VAL_CTYPE { 143 Ctlst.Lft.V = vptr.Ptr.(*float64) 144 } else { 145 Ctlst.Lft.S = vptr.Ptr.(*ControlSWType) 146 } 147 err = ctlrgtptr(value, &Ctlst.Rgt, Simc, Compnt, Mpath, Wd, Exsf, Schdl, Ctlst.Type) 148 } 149 150 if err != nil { 151 Err := fmt.Sprintf("%s = %s", s[:st], s[st+1:]) 152 Eprint("<Contrldata>", Err) 153 } 154 } else if s == "TVALV" { 155 flag_ignore = true 156 ValvControl(fi, Compnt, Schdl, Simc, Wd, &vptr) 157 } else { 158 Eprint("<Contrldata>", s) 159 } 160 161 s = fi.GetToken() 162 if len(s) == 0 || s[0] == ';' { 163 break 164 } 165 } 166 167 if !flag_ignore { 168 *Ct = append(*Ct, Contl) 169 *Cs = append(*Cs, Contl.Cst) 170 } 171 } 172 } 173 174 func ContrlCount(fi *EeTokens) (Nif, N int) { 175 ad := fi.GetPos() 176 var N1, N2 int 177 178 Nif, N = 0, 0 179 180 for fi.IsEnd() == false { 181 s := fi.GetToken() 182 if s[0] == '*' { 183 break 184 } 185 186 switch s { 187 case "if", "AND", "OR": 188 N1++ 189 case "TVALV": 190 N2++ 191 } 192 193 if strings.Contains(s, "=") { 194 N2++ 195 } 196 } 197 198 N = N2 199 Nif = N1 200 201 fi.RestorePos(ad) 202 203 return Nif, N 204 } 205 206 /* ------------------------------------------------------ */ 207 208 /* 制御条件式 (lft1 - lft2 ? rgt ) に関するポインター */ 209 210 func ctifdecode(_s string, ctlif *CTLIF, Simc *SIMCONTL, Compnt []*COMPNT, 211 Mpath []*MPATH, Wd *WDAT, Exsf *EXSFS, Schdl *SCHDL) { 212 var lft, op, rgt string // 左変数, 演算子, 右変数 213 var err int 214 var vptr VPTR 215 216 s := strings.Split(_s, " ") 217 lft, op, rgt = s[0], s[1], s[2] 218 219 st := strings.IndexRune(lft, '-') 220 if st != -1 { 221 lft = lft[:st] 222 } 223 224 // 演算対象の変数 その1を設定 225 vptr, _, _ = ctlvptr(lft, Simc, Compnt, Mpath, Wd, Exsf, Schdl) 226 227 ctlif.Type = vptr.Type // 演算の種類を設定 228 ctlif.Nlft = 1 229 if vptr.Type == VAL_CTYPE { 230 ctlif.Lft1.V = vptr.Ptr.(*float64) 231 } else { 232 ctlif.Lft1.S = vptr.Ptr.(*ControlSWType) 233 } 234 235 // 演算対象の変数 その2を設定 236 if st != -1 { 237 vptr, _, _ = ctlvptr(lft[st:], Simc, Compnt, Mpath, Wd, Exsf, Schdl) 238 239 if vptr.Type == VAL_CTYPE && ctlif.Type == vptr.Type { 240 ctlif.Nlft = 2 241 ctlif.Lft2.V = vptr.Ptr.(*float64) 242 } else { 243 Eprint("<ctifdecode>", lft[st+1:]) 244 } 245 } 246 247 // 比較演算子 Op の設定 248 err = 0 249 if op == ">" { 250 ctlif.Op = 'g' 251 } else if op == ">=" { 252 ctlif.Op = 'G' 253 } else if op == "<" { 254 ctlif.Op = 'l' 255 } else if op == "<=" { 256 ctlif.Op = 'L' 257 } else if op == "==" { 258 ctlif.Op = 'E' 259 } else if op == "!=" { 260 ctlif.Op = 'N' 261 } else { 262 err = 1 263 } 264 265 Errprint(err, "<ctifdecode>", _s) 266 267 ctlrgtptr(rgt, &ctlif.Rgt, Simc, Compnt, Mpath, Wd, Exsf, Schdl, ctlif.Type) 268 } 269 270 /* ------------------------------------------------------ */ 271 272 /* 条件式、設定式の右辺(定数、またはスケジュール設定値のポインター) */ 273 274 func ctlrgtptr(s string, rgt *CTLTYP, Simc *SIMCONTL, Compnt []*COMPNT, Mpath []*MPATH, Wd *WDAT, Exsf *EXSFS, Schdl *SCHDL, _type VPtrType) error { 275 var vptr VPTR 276 var err error 277 278 if _type == VAL_CTYPE && isstrdigit(s) { 279 var v float64 280 v, err = strconv.ParseFloat(s, 64) 281 if err == nil { 282 rgt.V = CreateConstantValuePointer(v) 283 } 284 } else { 285 switch s { 286 case "OFF": 287 rgt.S = new(ControlSWType) 288 *rgt.S = OFF_SW 289 case "ON": 290 rgt.S = new(ControlSWType) 291 *rgt.S = ON_SW 292 case "COOL": 293 rgt.S = new(ControlSWType) 294 *rgt.S = COOLING_SW 295 case "HEAT": 296 rgt.S = new(ControlSWType) 297 *rgt.S = HEATING_SW 298 default: 299 if _type == SW_CTYPE && strings.HasPrefix(s, "'") && len(s) > 2 { 300 rgt.S = new(ControlSWType) 301 *rgt.S = ControlSWType(s[1]) 302 } else { 303 vptr, _, err = ctlvptr(s, Simc, Compnt, Mpath, Wd, Exsf, Schdl) 304 if _type == vptr.Type { 305 if _type == VAL_CTYPE { 306 rgt.V = vptr.Ptr.(*float64) 307 } else { 308 rgt.S = vptr.Ptr.(*ControlSWType) 309 } 310 } else { 311 err = errors.New("Generated pointer type is not expected") 312 } 313 } 314 } 315 } 316 317 //Errprint(err, "<ctlrgtptr>", s) 318 return err 319 } 320 321 func NewCONTL() *CONTL { 322 contl := new(CONTL) 323 contl.Lgv = 0 324 contl.Type = ' ' 325 contl.Cif = nil 326 contl.AndCif = nil 327 contl.AndAndCif = nil 328 contl.OrCif = nil 329 contl.Cst = nil 330 return contl 331 } 332 333 func NewCTLST() *CTLST { 334 ctlst := new(CTLST) 335 ctlst.Type = ' ' 336 ctlst.PathType = ' ' 337 ctlst.Path = nil 338 return ctlst 339 } 340 341 func NewCTLIF() *CTLIF { 342 ctlif := new(CTLIF) 343 ctlif.Type = ' ' 344 ctlif.Op = ' ' 345 ctlif.Nlft = 0 346 return ctlif 347 }