📄 compiler.cpp
字号:
// Copyright (C) 1999-2005 Open Source Telecom Corporation.// // This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.// // This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.// // As a special exception, you may use this file as part of a free software// library without restriction. Specifically, if other files instantiate// templates or use macros or inline functions from this file, or you compile// this file and link it with other files to produce an executable, this// file does not by itself cause the resulting executable to be covered by// the GNU General Public License. This exception does not however// invalidate any other reasons why the executable file might be covered by// the GNU General Public License.//// This exception applies only to the code released under the name GNU// ccScript. If you copy code from other releases into a copy of GNU// ccScript, as the General Public License permits, the exception does// not apply to the code that you add in this way. To avoid misleading// anyone as to the status of such modified files, you must delete// this exception notice from them.//// If you write modifications of your own for GNU ccScript, it is your choice// whether to permit this exception to apply to your modifications.// If you do not wish that, delete this exception notice.//#include "engine.h"using namespace std;using namespace ost;ScriptCompiler::ScriptCompiler(ScriptCommand *cmd, const char *symset) :ScriptImage(cmd, symset){ inccount = 0; mlist = NULL; scrStream = (istream *)&scrSource;}void ScriptCompiler::fastBranch(ScriptInterp *interp){ Line *line; ScriptInterp::Frame *frame; Method m; unsigned maxstep = fastStepping; bool nongoto = false; frame = interp->getFrame(); if(frame->line == frame->script->first) nongoto = true; while(maxstep-- && NULL != (line = interp->getLine())) { m = line->scr.method; if(line->loop == 0xffff) { if(interp->getTrace()) return; interp->setFrame(); interp->execute(m); } else if(m == (Method)&ScriptMethods::scrBegin || m == (Method)&ScriptMethods::scrReturn) { interp->setFrame(); interp->execute(m); return; } else if(m == (Method)&ScriptMethods::scrGoto || m == (Method)&ScriptMethods::scrRestart) { if(nongoto) return; interp->setFrame(); interp->execute(m); return; } else return; }}bool ScriptCompiler::checkSegment(Name *scr){ return true;}const char *ScriptCompiler::preproc(const char *token){ return "unknown keyword";} const char *ScriptCompiler::getDefined(const char *token){ return getLast(token);}void ScriptCompiler::commit(void){ Name *scr, *target; const char *last = ""; NamedEvent *ev, *from; unsigned ecount; const char *en; char pbuf[65]; char *ep; while(inccount) include(incfiles[--inccount]); while(mlist) { scr = getScript(mlist->source); if(!scr) { if(mlist->source != last) slog.error("include from %s not found", mlist->source); goto cont; } ecount = 0; en = mlist->prefix; if(!*en) en = "*:"; target = mlist->target; from = scr->events; while(from) { if(!strnicmp(from->name, mlist->prefix, strlen(mlist->prefix))) { ev = (NamedEvent *)alloc(sizeof(NamedEvent)); ev->line = from->line; ev->name = from->name; ev->type = from->type; ev->next = target->events; target->events = ev; ++ecount; } from = from->next; } if(ecount) { setString(pbuf, sizeof(pbuf), en); ep = strchr(pbuf, ':'); if(ep) *ep = 0; slog.debug("included %s from %s; %d events", pbuf, mlist->source, ecount); }cont: last = mlist->source; mlist = mlist->next; } ScriptImage::commit();}char *ScriptCompiler::getToken(char **pre){ static char temp[513]; char *cp = temp + 1; char *base = temp + 1; char q; int level; if(pre) if(*pre) { cp = *pre; *pre = NULL; return cp; } if(*bp == '=') { ++bp; if(*bp == '{') { level = -1; while(*bp) { if(*bp == '}' && !level) break; if(*bp == '{') ++level; else if(*bp == '}') --level; *(cp++) = *(bp++); } if(*bp == '}') ++bp; *cp = 0; *base = 0x01; // special token return base; } if(*bp == ' ' || *bp == '\t' || !*bp) return ""; if(*bp == '\"' || *bp == '\'') { q = *(bp++); while(q) { switch(*bp) { case '\\': ++bp; if(!*bp) { q = 0; break; } switch(*bp) { case 't': *(cp++) = '\t'; ++bp; break; case 'b': *(cp++) = '\b'; ++bp; break; case 'n': *(cp++) = '\n'; ++bp; break; default: *(cp++) = *(bp++); } break; case 0: q = 0; break; default: if(*bp == q) { ++bp; q = 0; } else *(cp++) = *(bp++); } } *cp = 0; return base; } while(*bp != ' ' && *bp != '\t' && *bp) *(cp++) = *(bp++); *cp = 0; return base; } if(!quote) while(*bp == ' ' || *bp == '\t') ++bp; if(!quote && *bp == '#' && (!bp[1] || bp[1] == '!' || isspace(bp[1]))) return NULL; if(!quote && bp[0] == '%' && bp[1] == '%' && (!bp[2] || isspace(bp[2]))) return NULL; if(!*bp) { paren = 0; quote = false; return NULL; } if(*bp == '\"' && !quote) { ++bp; quote = true; } if(!quote && *bp == '{') { level = -1; while(*bp) { if(*bp == '}' && !level) break; if(*bp == '{') ++level; else if(*bp == '}') --level; *(cp++) = *(bp++); } if(*bp == '}') ++bp; *cp = 0; return base; } if(!quote) { if(*bp == ',' && paren) { ++bp; return ","; } retry: while(*bp && !isspace(*bp) && *bp != ',' && *bp != '=' && *bp != '(' && *bp != ')' ) *(cp++) = *(bp++); if(*bp == '(') ++paren; else if(*bp == ')') --paren; if(*bp == '=' && cp == base) { *(cp++) = *(bp++); goto retry; } if(*bp == '=' && cp == base + 1 && ispunct(*base)) { *(cp++) = *(bp++); goto retry; } if((*bp == '(' || *bp == ')') && cp == base) *(cp++) = *(bp++); *cp = 0; if(*bp == ',' && !paren) ++bp; else if(*bp == '=') *(--base) = *(bp); if(!strcmp(base, "==")) return ".eq."; if(!strcmp(base, "=")) return "-eq"; if(!strncmp(base, "!=", 2)) return ".ne."; if(!strncmp(base, "<>", 2)) return "-ne"; if(!strcmp(base, "<")) return "-lt"; if(!strcmp(base, "<=")) return "-le"; if(!strcmp(base, ">")) return "-gt"; if(!strcmp(base, ">=")) return "-ge"; return base; } if(*bp == '\\' && (bp[1] == '%' || bp[1] == '&' || bp[1] == '.' || bp[1] == '#')) { ++bp; *(cp++) = '{'; *(cp++) = *(bp++); }requote: if(isalnum(*bp) || strchr("~/:,. \t\'", *bp)) { while(isalnum(*bp) || strchr("~=/:,. \t\'", *bp)) *(cp++) = *(bp++); } else while(!isspace(*bp) && *bp && *bp != '\"') *(cp++) = *(bp++); if(*bp == '\n' || !*bp) paren = 0; if(*bp == '\n' || !*bp || *bp == '\"') quote = false; if(*bp == '\\' && bp[1]) { ++bp; switch(*bp) { case 0: break; case 't': *(cp++) = '\t'; ++bp; break; case 'b': *(cp++) = '\b'; ++bp; break; case 'n': *(cp++) = '\n'; ++bp; break; default: *(cp++) = *(bp++); } goto requote; } if(*bp == '\n' || *bp == '\"') ++bp; *cp = 0; return base;}int ScriptCompiler::compile(const char *scrname){ char buffer[129]; char *token; char *ext;#ifdef WIN32 char *l1, *l2; setString(buffer, sizeof(buffer), scrname); l1 = strrchr(buffer, '/'); l2 = strrchr(buffer, '\\'); if(l1 > l2) token = l1; else token = l2;#else setString(buffer, sizeof(buffer), scrname); token = strrchr(buffer, '/');#endif if(!token) token = buffer; else ++token; ext = strrchr(token, '.'); if(ext) { if(strstr(exec_extensions, ext) == NULL) *ext = 0; } return compile(scrname, token);}Script::Name *ScriptCompiler::include(const char *token){ char buffer[256]; const char *local = cmds->getLast("binclude"); const char *prefix = cmds->getLast("include"); const char *cp; Name *inc = getScript(token); if(inc) return inc; if(!prefix) return NULL; snprintf(buffer, sizeof(buffer), "virtual.%s", token); cp = cmds->getLast(buffer); if(local) { if(cp) snprintf(buffer, sizeof(buffer), "%s/%s_%s.mac", local, token, cp); else snprintf(buffer, sizeof(buffer), "%s/%s.mac", local, token); if(!isFile(buffer) || !canAccess(buffer)) local = NULL; } if(!local) { if(cp) snprintf(buffer, sizeof(buffer), "%s/%s_%s.mac", prefix, token, cp); else snprintf(buffer, sizeof(buffer), "%s/%s.mac", prefix, token); if(!isFile(buffer) || !canAccess(buffer)) return NULL; } compile(buffer, (char *)token); return getScript(token);}int ScriptCompiler::compileDefinitions(const char *filename){ char buffer[128]; int rtn; const char *cp = strrchr(filename, '.'); if(!cp || stricmp(cp, ".def")) return 0; cp = strrchr(filename, '/');#ifdef WIN32 if(!cp) cp = strrchr(filename, '\\'); if(!cp) cp = strchr(filename, ':');#endif if(!cp) { cp = cmds->getLast("include"); if(cp) { snprintf(buffer, sizeof(buffer), "%s/%s", cp, filename); filename = buffer; } } if(!isFile(filename) || !canAccess(filename)) return 0; scrSource.open(filename); if(!scrSource.is_open()) return 0; Script::use_definitions = true; rtn = compile((istream *)&scrSource, "definitions", filename); scrSource.close(); scrSource.clear(); return rtn;}int ScriptCompiler::compile(const char *scrname, char *name){ int rtn; scrSource.open(scrname); if(!scrSource.is_open()) return 0; rtn = compile((istream *)&scrSource, name, scrname); scrSource.close(); scrSource.clear(); return rtn;}int ScriptCompiler::compile(istream *str, char *name, const char *scrname){ const char *errmsg = NULL; const char *basename = name; char filename[65]; unsigned lnum = 0; char namebuf[256]; char gvarname[128]; char path[128]; char csname[128]; char *command, *token, *pretoken = NULL; char *args[SCRIPT_MAX_ARGS + 1]; int maxargs = SCRIPT_MAX_ARGS; const char *err; char *cp = (char *)strrchr(scrname, '.');// const char *var = cmds->getLast("datafiles"); bool trapflag; int argc, key, tlen, initkey = 0, initcount = 0; unsigned i; unsigned short count, number, total = 0; size_t gvarlen; NamedEvent *events, *esave; Name *script, *ds; Line *line, *last; unsigned long addmask, submask, trapmask, mask, cmask = 0; Method handler; unsigned char loopid, looplevel; size_t offset = 0; Name *base = NULL, *init = NULL; bool sub = false; streampos pos; bool ignore; scrAccess access = scrPUBLIC; char temp[64]; char *pmode = NULL; char *ftoken = NULL; char *filter; bool bm = false; bool first = true; unsigned long addPmask = 0, subPmask = (unsigned long)~0; unsigned long addPmask1 = 0, subPmask1 = (unsigned long)~0; char catchname[256]; const char *embed = NULL; bool mscmd = false, execflag = false; bool apps = false; bool defs = false; bool ripple = cmds->ripple; bool wrapper = false; merge_t *merge; if(strstr(".bat.cmd", cp)) mscmd = true; if(strstr(apps_extensions, cp)) apps = true; else if(strstr(exec_extensions, cp)) { snprintf(namebuf, sizeof(namebuf), "%s:%s", exec_prefix, name); name = namebuf; embed = exec_token; wrapper = true; } if(!strnicmp(name, exec_prefix, strlen(exec_prefix))) wrapper = true; buffer = (char *)malloc(512); bufsize = 512; scrStream = str; if(cp && !stricmp(cp, ".mac")) { bm = true; ripple = false; } if(cp && !stricmp(cp, ".scr")) ripple = false;#ifdef WIN32 if(cp && !stricmp(cp, ".ini")) ripple = true;#endif if(cp && !stricmp(cp, ".conf")) ripple = true; if(cp && !stricmp(cp, ".def")) { ripple = false; defs = true; } if(bm || defs) access = scrPROTECTED; gvarname[0] = '%'; snprintf(gvarname + 1, 56, "%s.", name); gvarlen = strlen(gvarname);#ifdef WIN32 const char *l1 = strrchr(scrname, '/'); const char *l2 = strrchr(scrname, '\\'); if(l1 > l2) cp = (char *)l1; else cp = (char *)l2;#else cp = (char *)strrchr(scrname, '/');#endif if(cp) ++cp; else cp = (char *)scrname; snprintf(filename, sizeof(filename), "%s", cp);compile: trapflag = false; count = number = 0; last = NULL; addmask = submask = trapmask = 0; handler = NULL; loopid = looplevel = 0; bool then = false; events = NULL; setString(csname, sizeof(csname), name); cp = strstr(csname, "::"); if(cp && !stricmp(cp, "::main") && !ripple) { initkey = SCRIPT_INDEX_SIZE; *cp = 0; } if(ripple && cp) initkey = SCRIPT_INDEX_SIZE; key = Script::getIndex(csname); if(first && (bm || defs)) initkey = SCRIPT_INDEX_SIZE; else if(first) initkey = key; current = script = (Name *)alloc(sizeof(Name)); memset(script, 0, sizeof(Name)); script->name = alloc(csname); script->mask = 0; script->events = NULL; addPmask1 = addPmask; subPmask1 = subPmask; addPmask = 0; subPmask = (unsigned long)~0; if(!first) script->next = index[key]; script->filename = alloc(filename); if(first) init = script; if(pmode) { if(!strnicmp(pmode, "pub", 3) || !stricmp(pmode, "program")) script->access = scrPUBLIC; else if(!strnicmp(pmode, "priv", 4) || !stricmp(pmode, "state")) script->access = scrPRIVATE; else if(!strnicmp(pmode, "prot", 4)) script->access = scrPROTECTED; else if(!strnicmp(pmode, "fun", 3)) script->access = scrFUNCTION; else if(!stricmp(pmode, "local")) script->access = scrLOCAL; else script->access = access; } else script->access = access; if(!first) index[key] = script; pmode = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -