示例#1
0
文件: execute.cpp 项目: gnaghi/bass
bool Bass::executeInstruction(Instruction& i) {
  activeInstruction = &i;
  string s = i.statement;
  evaluateDefines(s);

  if(s.match("macro ?*(*) {") || s.match("global macro ?*(*) {")) {
    bool local = s.beginsWith("global ") == false;
    s.ltrim<1>("global ");
    s.trim<1>("macro ", ") {");
    lstring p = s.split<1>("(");
    bool scoped = p(0).beginsWith("scope ");
    p(0).ltrim<1>("scope ");
    lstring a = p(1).empty() ? lstring{} : p(1).qsplit(",").strip();
    setMacro(p(0), a, ip, scoped, local);
    ip = i.ip;
    return true;
  }

  if(s.match("define ?*(*)") || s.match("global define ?*(*)")) {
    bool local = s.beginsWith("global ") == false;
    s.ltrim<1>("global ");
    lstring p = s.trim<1>("define ", ")").split<1>("(");
    setDefine(p(0), p(1), local);
    return true;
  }

  if(s.match("evaluate ?*(*)") || s.match("global evaluate ?*(*)")) {
    bool local = s.beginsWith("global ") == false;
    s.ltrim<1>("global ");
    lstring p = s.trim<1>("evaluate ", ")").split<1>("(");
    setDefine(p(0), evaluate(p(1)), local);
    return true;
  }

  if(s.match("variable ?*(*)") || s.match("global variable ?*(*)")) {
    bool local = s.beginsWith("global ") == false;
    s.ltrim<1>("global ");
    lstring p = s.trim<1>("variable ", ")").split<1>("(");
    setVariable(p(0), evaluate(p(1)), local);
    return true;
  }

  if(s.match("if ?* {")) {
    s.trim<1>("if ", " {").strip();
    bool match = evaluate(s, Evaluation::Strict);
    ifStack.append(match);
    if(match == false) {
      ip = i.ip;
    }
    return true;
  }

  if(s.match("} else if ?* {")) {
    if(ifStack.last()) {
      ip = i.ip;
    } else {
      s.trim<1>("} else if ", " {").strip();
      bool match = evaluate(s, Evaluation::Strict);
      ifStack.last() = match;
      if(match == false) {
        ip = i.ip;
      }
    }
    return true;
  }

  if(s.match("} else {")) {
    if(ifStack.last()) {
      ip = i.ip;
    } else {
      ifStack.last() = true;
    }
    return true;
  }

  if(s.match("} endif")) {
    ifStack.removeLast();
    return true;
  }

  if(s.match("while ?* {")) {
    s.trim<1>("while ", " {").strip();
    bool match = evaluate(s, Evaluation::Strict);
    if(match == false) ip = i.ip;
    return true;
  }

  if(s.match("} endwhile")) {
    ip = i.ip;
    return true;
  }

  if(s.match("?*(*)")) {
    lstring p = string{s}.rtrim<1>(")").split<1>("(");
    lstring a = p(1).empty() ? lstring{} : p(1).qsplit(",").strip();
    string name = {p(0), ":", a.size()};  //arity overloading
    if(auto macro = findMacro({name})) {
      struct Parameter {
        enum class Type : unsigned { Define, Variable } type;
        string name;
        string value;
      };

      vector<Parameter> parameters;
      for(unsigned n = 0; n < a.size(); n++) {
        lstring p = macro().parameters(n).split<1>(" ").strip();
        if(p.size() == 1) p.prepend("define");

        if(p(0) == "define") parameters.append({Parameter::Type::Define, p(1), a(n)});
        else if(p(0) == "string") parameters.append({Parameter::Type::Define, p(1), text(a(n))});
        else if(p(0) == "evaluate") parameters.append({Parameter::Type::Define, p(1), evaluate(a(n))});
        else if(p(0) == "variable") parameters.append({Parameter::Type::Variable, p(1), evaluate(a(n))});
        else error("unsupported parameter type: ", p(0));
      }

      StackFrame frame;
      stackFrame.append(frame);
      stackFrame.last().ip = ip;
      stackFrame.last().scoped = macro().scoped;

      if(macro().scoped) {
        scope.append(p(0));
      }

      setDefine("#", {"_", macroInvocationCounter++}, true);
      for(auto& parameter : parameters) {
        if(parameter.type == Parameter::Type::Define) setDefine(parameter.name, parameter.value, true);
        if(parameter.type == Parameter::Type::Variable) setVariable(parameter.name, integer(parameter.value), true);
      }

      ip = macro().ip;
      return true;
    }
  }

  if(s.match("} endmacro")) {
    ip = stackFrame.last().ip;
    if(stackFrame.last().scoped) scope.removeLast();
    stackFrame.removeLast();
    return true;
  }

  if(assemble(s)) {
    return true;
  }

  evaluate(s);
  return true;
}
示例#2
0
文件: lexer.cpp 项目: fstudio/nmake
UCHAR
processIncludeFile(
    char *s
    )
{
    MACRODEF *m;
    struct _finddata_t finddata;
    NMHANDLE searchHandle;
    char *t, *p, *u;
    int c = 0;
    int i;

    if (!*s || *s == '#') {
        makeError(line, SYNTAX_NO_NAME);
    }

    if ((t = _tcspbrk(s,"\t#"))) {
        if (*t == '#') {
            c = *t;
        }

        *t = '\0';

        if (!c) {
            for (u = t; *++u;) {        // check for extra
                if (*u == '#') {
                    break;              // text on line
                }

                if (!WHITESPACE(*u)) {
                    makeError(line, SYNTAX_UNEXPECTED_TOKEN, u);
                }
            }
        }
    } else {
        t = s + _tcslen(s);
    }

	// remove trailing white space
	while (t > s) {
		char *prev;
		prev = _tcsdec(s, t);
		if (!WHITESPACE(*prev))
			break;
		t = prev;
	}
	*t = '\0';

    if (*s == '<' && *(t-1) == '>') {
        char *pt;

        *--t = '\0';
        p = removeMacros(++s);
        p = p == s ? makeString(s) : p;
        t = (m = findMacro("INCLUDE")) ? m->values->text : (char*) NULL;
        if (t != NULL) {        // expand INCLUDE macro before passing it on
            char * pt1;

            pt1= makeString(t);
            pt = removeMacros(pt1);
            if (pt != pt1) {
                FREE(pt1);             // we've got a new string, free old one
            }
        } else {
            pt = NULL;
        }

        if (!(u = searchPath(pt, p, &finddata, &searchHandle))) {
            makeError(line, CANT_OPEN_FILE, p);
        }

        if (pt) {
            FREE(pt);
        }

        FREE(p);
        s = u;
    } else {
        if (*s == '"' && *(t-1) == '"') {
            *--t = '\0';
            ++s;
        }
        p = removeMacros(s);
        p = p == s ? makeString(s) : p;
        if (!findFirst(p, &finddata, &searchHandle)) {
            if (!_tcspbrk(p, "\\/:")) {
                //use C sematics for include
                for (i = incTop;i >= 0;i--) {
                    t = (i == incTop) ? fName : incStack[i].name;
                    if (!(t = getPath(t)))
                        continue;
                    u = (char *)allocate(_tcslen(t) + 1 + _tcslen(p) + 1);
                    _tcscat(_tcscat(_tcscpy(u, t), PATH_SEPARATOR), p);
                    if (findFirst(u, &finddata, &searchHandle)) {
                        s = u;
                        FREE(t);
                        break;
                    }
                    FREE(t);
                    FREE(u);
                }
                FREE(p);
                if (i < 0) {
                    makeError(line, CANT_OPEN_FILE, s);
                }
            } else {
                makeError(line, CANT_OPEN_FILE, p);
            }
        }
    }

    for (i = 0; i < incTop; ++i) {      // test for cycles
        if (!_tcsicmp(s,incStack[i].name)) {
            makeError(line, CYCLE_IN_INCLUDES, s);
        }
    }

    incStack[incTop].file = file;       // push info on stack
    incStack[incTop].line = line;
    incStack[incTop++].name = fName;
    currentLine = 0;

    if (!(file = OpenValidateMakefile(s,"rt"))) {   // read, text mode
        makeError(line,CANT_OPEN_FILE,s);
    }

    fName = makeString(s);
    line = 1;
    colZero = TRUE;                     // parser needs to see some kind of
    c = lgetc();                        //  newline to initialize it for this

    if ((colZero = (BOOL) !WHITESPACE(c))) {  // file
        UngetTxtChr(c,file);
        line=0;                         // We did not start reading the file
        return(NEWLINE);
    }

    return(NEWLINESPACE);
}
示例#3
0
文件: action.cpp 项目: ArildF/masters
BOOL
putMacro(
    char *name,
    char *value,
    UCHAR flags
    )
{
    MACRODEF *p;
    STRINGLIST *q;
    BOOL defined = FALSE;
    BOOL fSyntax = TRUE;

    // Convert path separators to the native path separator.
    // Do that with a copy of the original string so we don't change
    // the original.
    value = makeString(value);
#if PLATFORM_UNIX
    char *tmp = value;
    while ((tmp = FindFirstPathSeparator(tmp))) {
        *tmp++ = PATH_SEPARATOR_CHAR;
    }
#endif // PLATFORM_UNIX

    // Inherit macro definitions.  Call removeMacros() to expand sub-macro
    // definitions.  Must be done before macro is put in table, else
    // recursive definitions won't work.

    if (ON(flags, M_NON_RESETTABLE)) {
        if (*value)
            if ((putEnvStr(name,removeMacros(value)) == -1))
                makeError(currentLine, OUT_OF_ENV_SPACE);
    } else
    if (fInheritUserEnv &&
        OFF(gFlags, F1_USE_ENVIRON_VARS) &&
        getenv(name)
       ) {
        if ((p = findMacro(name))) {  // don't let user
            if (CANT_REDEFINE(p))   // redefine cmdline
                return(FALSE);      // macros, MAKE, etc.
        }
        if ((putEnvStr(name,removeMacros(value)) == -1))
            makeError(currentLine, OUT_OF_ENV_SPACE);
    }

    fInheritUserEnv = (BOOL)FALSE;
    if ((p = findMacro(name))) {      // don't let user
        if (CANT_REDEFINE(p))       // redefine cmdline
            return(FALSE);          // macros, MAKE, etc.
    }

    q = makeNewStrListElement();
    q->text = value;

    if (!p) {
        p = makeNewMacro();
        p->name = name;
        assert(p->flags == 0);
        assert(p->values == NULL);
    } else
        defined = TRUE;

    p->flags &= ~M_UNDEFINED;       // Is no longer undefined
    p->flags |= flags;              // Set flags to union of old and new
    prependItem((STRINGLIST**)&(p->values), (STRINGLIST*)q);
    if (!defined)
        insertMacro((STRINGLIST*)p);

    if (OFF(flags, M_LITERAL) && _tcschr(value, '$')) {     // Check for cyclic Macro Definitions
        SET(p->flags, M_EXPANDING_THIS_ONE);
        // NULL -> don't build list
        fSyntax = findMacroValues(value, NULL, NULL, name, 1, 0, flags);
        CLEAR(p->flags, M_EXPANDING_THIS_ONE);
    }

    if (!fSyntax) {
        p->values = NULL;
        p->flags |= M_UNDEFINED;
        //return(FALSE);
		// return TRUE since p has been added to the macro table
		// Otherwise the caller may free name and value leaving
		// dangling pointers in the macro table.                            
		return(TRUE);
    }
    return(TRUE);
}