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  }