static Void AddMap(ValueMap &m, LPCTSTR k, SValueType *v) { SValueType* v_old; if (m.Lookup(k, v_old)) delete v_old; m.SetAt(k, v); }
CTobCompiler::EToken CTobCompiler::CompilePass1() { EToken r, LastToken; CString str, buf, sizebuf; CByteArray* bin; SValueType* val; SExpression* exp; for(;;) { BOOL bSkipGetToken = FALSE; if ((r = GetToken(str)) <= 0) return r; _SkipGetToken: if (r == SYM_DEF) { /* if (m_bin.GetSize() > 0) { m_err = "const token can not defined after data"; return ERR_NORMAL; } */ if ((r = GetToken(str)) < 0) return r; if (r != SYM_TOKEN) { m_err = "not found token after '@'"; return ERR_NORMAL; } if (str == "_IGNORECASE") { m_Option.bIgnoreCase = TRUE; continue; } if ((r = GetToken(buf)) < 0) return r; if (r == SYM_BIN) { bin = new CByteArray; if ((r = GetBinary(*bin)) < 0) { delete bin; return r; } AddMap(m_binmap, str, bin); } else if (r == SYM_STR) { bin = new CByteArray; if ((r = GetString(*bin)) < 0) { delete bin; return r; } AddMap(m_binmap, str, bin); } else if (r == SYM_INT) { ULONG Length; BOOL bHex = (buf[0] == '0' && buf[1] == 'x'); r = GetToken(sizebuf); LastToken = r; if (r == SYM_TYPE) { r = GetToken(sizebuf); if (r != SYM_TOKEN) { m_err = "not found type after ':'"; return ERR_NORMAL; } Length = GetSizeFromType(sizebuf[0]); if (Length == -1) { m_err.Format("unknown type '%c' after ':'", sizebuf[0]); return ERR_NORMAL; } } else { Length = -1; } val = new SValueType((int)strtoul(buf, NULL, bHex ? 16 : 10), Length); AddMap(m_valmap, str, val); if (Length == -1) bSkipGetToken = TRUE; r = SYM_INT; } else if (r == SYM_FLOAT) { AddMap(m_valmap, str, new SValueType(atof(buf))); } else { m_err.Format("not found '[' or ''' or '\"' or number after '@%s'", (LPCTSTR)str); return ERR_NORMAL; } if (m_Option.bIgnoreCase) str.MakeUpper(); if (str == "_DEFI") { if (r != SYM_INT || val->ival < 1 || val->ival > 4) { m_err = "_DEFI must be 1/2/3/4"; return ERR_NORMAL; } m_Option.DefInt = val->ival; } else if (str == "_DEFF") { if (r != SYM_INT || val->ival != 4 && val->ival != 8) { m_err = "_DEFF must be 4/8"; return ERR_NORMAL; } m_Option.DefFloat = val->ival; } else if (str == "_MOD") { if (r != SYM_INT) { m_err = "_MOD must be number"; return ERR_NORMAL; } while (m_bin.GetSize() % val->ival) m_bin.Add(0); } else if (str == "_INCLUDE") { FILE *fsrc; WCHAR szPath[MAX_PATH]; CByteArray *bin; if (m_Option.bIgnoreCase) str.MakeLower(); if (!m_binmap.Lookup(str, bin)) continue; m_binmap.RemoveKey(str); MultiByteToWideChar( CP_GB2312, 0, (LPSTR)bin->GetData(), -1, szPath, countof(szPath)); delete bin; fsrc = m_fsrc; m_fsrc = _wfopen(szPath, L"rb"); if (m_fsrc == NULL) { m_fsrc = fsrc; m_err.Format("can't open include file '%S'", szPath); return ERR_SEVERE; } else { EToken r; for(;;) { r = CompilePass1(); if (r == ERR_EOF) break; if (r < 0) { if (!ErrorHandlerInternal(GetErrorString(m_err))) break; } if (r == ERR_SEVERE) break; } fclose(m_fsrc); m_fsrc = fsrc; if (r < 0) return r; } } if (bSkipGetToken) { str = sizebuf; r = LastToken; goto _SkipGetToken; } } else if (r == SYM_BIN) { if ((r = GetBinary(m_bin)) < 0) return r; } else if (r == SYM_STR) { if ((r = GetString(m_bin)) < 0) return r; } else if (r == SYM_TOKEN) { if (!m_binmap.Lookup(str, bin)) { m_err.Format("unknown token '%s'", (LPCTSTR)str); return ERR_NORMAL; } m_bin.Append(*bin); } else if (r == SYM_LABEL) { if ((r = GetToken(str)) < 0) return r; if (r != SYM_TOKEN) { m_err = "not found token after '#'"; return ERR_NORMAL; } if (m_valmap.Lookup(str, val)) { m_err.Format("already defined label token '%s'", (LPCTSTR)str); return ERR_NORMAL; } m_valmap.SetAt(str, new SValueType(m_bin.GetSize())); } else if (r == SYM_EXP_BEGIN) { int i = m_exparr.GetSize(); do { int len = m_Option.DefInt; BOOL hastype = FALSE; exp = new SExpression(m_bin.GetSize(), m_line); for(;;) { if ((r = GetToken(buf)) < 0) { delete exp; return r; } if (r == SYM_TOKEN) { val = NULL; if (!hastype && len > 0 && m_valmap.Lookup(buf, val) && val->isfloat) len = -m_Option.DefFloat; exp->m_item.Add(buf); if (val != NULL && val->m_size != -1) len = val->isfloat ? -val->m_size : val->m_size; } else if (r == SYM_ADD) { exp->m_item.Add("+"); } else if (r == SYM_SUB) { exp->m_item.Add("-"); } else if (r == SYM_DEF) { exp->m_item.Add("@"); } else if (r == SYM_INT) { exp->m_item.Add(buf); } else if (r == SYM_FLOAT) { if (!hastype && len > 0) len = -m_Option.DefFloat; exp->m_item.Add(buf); } else if (r == SYM_TYPE) { int newlen; if ((r = GetToken(buf)) < 0) { delete exp; return r; } if (r != SYM_TOKEN) { delete exp; m_err = "not found type after ':'"; return ERR_NORMAL; } newlen = GetSizeFromType(buf[0]); if (newlen == -1) { delete exp; m_err.Format("unknown type '%c' after ':'", buf[0]); return ERR_NORMAL; } if (hastype && newlen != len) { delete exp; m_err = "found different types in one expression"; return ERR_NORMAL; } hastype = TRUE; len = newlen; } else if (r == SYM_BIN) { if (exp->m_item.GetSize() > 0) { delete exp; m_err = "found different types in one expression"; return ERR_NORMAL; } if ((r = GetBinary(m_bin)) < 0) { delete exp; return r; } } else if (r == SYM_STR) { if (exp->m_item.GetSize() > 0) { delete exp; m_err = "found different types in one expression"; return ERR_NORMAL; } if ((r = GetString(m_bin)) < 0) { delete exp; return r; } } else if (r == SYM_NEXT || r == SYM_EXP_END) { break; } else { delete exp; m_err.Format("unknown or bad symbol1 '%s' in expression", (LPCTSTR)str); return ERR_NORMAL; } } if (exp->m_item.GetSize() <= 0) { delete exp; } else { exp->m_size = len; m_exparr.Add(exp); if (len < 0) len = -len; while(len--) m_bin.Add(0); } } while(r != SYM_EXP_END); for(int j = m_exparr.GetSize(); i < j; ++i) m_exparr[i]->m_self = m_bin.GetSize(); } else { m_err.Format("unknown or bad symbol2 '%s'", (LPCTSTR)str); return ERR_NORMAL; } } }