Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/workflows/build-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -946,6 +946,37 @@ jobs:
fi
echo "[array-index] cached array indexing gives the same values"

- name: Postfix ++ and -- on an array element (Non-20.04)
if: matrix.id != 'docker-ubuntu-20.04'
shell: bash
run: |
set -eo pipefail
# Postfix ++ and -- ignored the index of an array element, saw several
# values, and stopped with the multi-valued variable error.
# Prefix ++x[i] worked. Now x[i]++ changes that element and returns
# its old value, in the interpreter and in compiled analyzers.
FIX=.github/workflows/tests/postfix-index
rm -rf "$FIX/logs" "$FIX/input/text.txt_log"
mkdir -p "$FIX/logs"
./bin/nlp -ANA "$FIX" -WORK ./ "$FIX/input/text.txt"
OUT="$FIX/input/text.txt_log/output.txt"
if [ ! -f "$OUT" ]; then
echo "FAIL(postfix-index): no output.txt -- the analyzer did not build"; exit 1
fi
got=$(tr -d '\r' < "$OUT")
want=$(printf '%s\n' \
'inc returns 20, now 10 21 30' \
'dec returns 30, now 10 21 29' \
'padded: 0 0 1 length 6' \
'string: 42' \
'local: 0 2' \
'scalar: 7 then 8' \
'node: 5 6')
if [ "$got" != "$want" ]; then
echo "FAIL(postfix-index): output.txt was:"; echo "$got"; echo "wanted:"; echo "$want"; exit 1
fi
echo "[postfix-index] x[i]++ and x[i]-- change that element"

- name: factorial() up to 20! (Non-20.04)
if: matrix.id != 'docker-ubuntu-20.04'
shell: bash
Expand Down
30 changes: 30 additions & 0 deletions .github/workflows/build-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,36 @@ jobs:
fi
echo "[array-index] cached array indexing gives the same values"

- name: Postfix ++ and -- on an array element
shell: bash
run: |
set -eo pipefail
# Postfix ++ and -- ignored the index of an array element, saw several
# values, and stopped with the multi-valued variable error.
# Prefix ++x[i] worked. Now x[i]++ changes that element and returns
# its old value, in the interpreter and in compiled analyzers.
FIX=.github/workflows/tests/postfix-index
rm -rf "$FIX/logs" "$FIX/input/text.txt_log"
mkdir -p "$FIX/logs"
./bin/Release/nlp.exe -ANA "$FIX" -WORK ./ "$FIX/input/text.txt"
OUT="$FIX/input/text.txt_log/output.txt"
if [ ! -f "$OUT" ]; then
echo "FAIL(postfix-index): no output.txt -- the analyzer did not build"; exit 1
fi
got=$(tr -d '\r' < "$OUT")
want=$(printf '%s\n' \
'inc returns 20, now 10 21 30' \
'dec returns 30, now 10 21 29' \
'padded: 0 0 1 length 6' \
'string: 42' \
'local: 0 2' \
'scalar: 7 then 8' \
'node: 5 6')
if [ "$got" != "$want" ]; then
echo "FAIL(postfix-index): output.txt was:"; echo "$got"; echo "wanted:"; echo "$want"; exit 1
fi
echo "[postfix-index] x[i]++ and x[i]-- change that element"

- name: factorial() up to 20!
shell: bash
run: |
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/tests/postfix-index/input/text.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
word
3 changes: 3 additions & 0 deletions .github/workflows/tests/postfix-index/spec/analyzer.seq
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
tokenize nil #
nlp postfix # x[i]++ and x[i]-- on array elements
nlp nodevar # on a node variable
15 changes: 15 additions & 0 deletions .github/workflows/tests/postfix-index/spec/nodevar.nlp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
###############################################
# FILE: nodevar.nlp
# SUBJ: Postfix ++ on an element of a node variable's array.
###############################################

@NODES _ROOT

@POST
N("c")[0] = 5;
N("c")[1] = 5;
N("c")[1]++;
"output.txt" << "node: " << N("c")[0] << " " << N("c")[1] << "\n";
noop();
@RULES
_xNIL <- _xALPHA @@
43 changes: 43 additions & 0 deletions .github/workflows/tests/postfix-index/spec/postfix.nlp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
###############################################
# FILE: postfix.nlp
# SUBJ: Postfix ++ and -- on an array element. They ignored the index,
# saw several values, and failed with "Can't increment
# multi-valued variable". Prefix ++x[i] already worked.
# NOTE: Part of the postfix-index regression; expected output is in
# the CI step.
###############################################

@CODE
G("a")[0] = 10;
G("a")[1] = 20;
G("a")[2] = 30;

L("r") = G("a")[1]++;
"output.txt" << "inc returns " << L("r") << ", now " << G("a")[0] << " " << G("a")[1] << " " << G("a")[2] << "\n";

L("r") = G("a")[2]--;
"output.txt" << "dec returns " << L("r") << ", now " << G("a")[0] << " " << G("a")[1] << " " << G("a")[2] << "\n";

# Past the end: pads with zeros, like assigning to x[i].
G("a")[5]++;
"output.txt" << "padded: " << G("a")[3] << " " << G("a")[4] << " " << G("a")[5] << " length " << arraylength(G("a")) << "\n";

# A numeric string element.
G("s")[0] = "x";
G("s")[1] = "41";
G("s")[1]++;
"output.txt" << "string: " << G("s")[1] << "\n";

# An index from an expression, on a local array.
L("x")[0] = 1;
L("x")[1] = 1;
L("i") = 1;
L("x")[L("i")]++;
L("x")[L("i") - 1]--;
"output.txt" << "local: " << L("x")[0] << " " << L("x")[1] << "\n";

# Plain variables are unchanged.
G("n") = 7;
L("r") = G("n")++;
"output.txt" << "scalar: " << L("r") << " then " << G("n") << "\n";
@@CODE
5 changes: 5 additions & 0 deletions include/Api/lite/Arun.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class Seqn;
class Nlppp;
class RFASem;
class Iarg; // 03/11/02 AM.
class Ipair; // x[i]++ helpers.
class CG; // 12/02/02 AM.

// May want to determine this for each analyzer or pass.
Expand Down Expand Up @@ -771,6 +772,10 @@ class LITE_API Arun
static RFASem *minus(RFASem *);

// Postunary.
static Iarg *index_arg(Ipair *pair, long long index); // x[i], padded.
static bool bump_arg(Iarg *arg, long long delta, long long &old);
static long long postinc(int,_TCHAR*,int,RFASem*,Nlppp*); // x[expr]++
static long long postdec(int,_TCHAR*,int,RFASem*,Nlppp*); // x[expr]--
static long long postinc(RFASem *,Nlppp *);
static long long postinc( // 06/02/00 AM.
int typ,
Expand Down
104 changes: 104 additions & 0 deletions lite/Arun.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13161,6 +13161,63 @@ return !flg;
}


/********************************************
* FN: INDEX_ARG
* SUBJ: Element INDEX of a variable's values, padding with zeros up to it,
* as assigning to x[i] does. For postfix x[i]++ and x[i]--.
********************************************/

Iarg *Arun::index_arg(Ipair *pair, long long index)
{
if (!pair || index < 0)
return 0;
Dlist<Iarg> *vals = pair->getVals();
if (!vals)
{
vals = new Dlist<Iarg>();
pair->setVals(vals);
}
long reached = 0;
Delt<Iarg> *darg = vals->getNthCached((long) index, reached);
if (!darg)
{
for (long long ii = reached; ii <= index; ++ii)
vals->rpush(new Iarg(0LL));
darg = vals->getLast();
}
return darg->getData();
}


/********************************************
* FN: BUMP_ARG
* SUBJ: Add DELTA to a numeric (or numeric-string) value in place.
* RET: True if done; OLD gets the value before the change.
********************************************/

bool Arun::bump_arg(Iarg *arg, long long delta, long long &old)
{
old = 0;
if (!arg)
return false;
switch (arg->getType())
{
case IANUM:
old = arg->getNum();
arg->setNum(old + delta);
return true;
case IASTR:
if (!str_to_long(arg->getStr(), old))
return false;
arg->setType(IANUM);
arg->setNum(old + delta);
return true;
default:
return false;
}
}


/********************************************
* FN: POSTINC
* CR: 06/02/00 AM.
Expand All @@ -13181,6 +13238,16 @@ Ipair *pair;
Ivar::getVar((enum Ivartype)typ,varname,nelt,nlppp,/*UP*/pair);
if (!pair)
return ret; // 06/05/00 AM.
if (index >= 0) // x[i]++ : the indexed element.
{
if (!bump_arg(index_arg(pair, index), 1, ret))
{
std::_t_strstream gerrStr;
gerrStr << _T("[inc: Error. Bad type.]") << std::ends;
nlppp->parse_->errOut(&gerrStr,false);
}
return ret;
}
Dlist<Iarg> *vals = pair->getVals();

Delt<Iarg> *darg;
Expand Down Expand Up @@ -13240,6 +13307,16 @@ Ipair *pair;
Ivar::getVar((enum Ivartype)typ,varname,nelt,nlppp,/*UP*/pair);
if (!pair)
return ret; // 06/05/00 AM.
if (index >= 0) // x[i]-- : the indexed element.
{
if (!bump_arg(index_arg(pair, index), -1, ret))
{
std::_t_strstream gerrStr;
gerrStr << _T("[dec: Error. Bad type.]") << std::ends;
nlppp->parse_->errOut(&gerrStr,false);
}
return ret;
}
Dlist<Iarg> *vals = pair->getVals();

Delt<Iarg> *darg;
Expand Down Expand Up @@ -13283,6 +13360,33 @@ return ret;
/******************************************************************************/




// x[expr]++ / x[expr]-- where the index is an expression.
long long Arun::postinc(int typ, _TCHAR *varname, int nelt,
RFASem *index_sem, Nlppp *nlppp)
{
bool ok = false;
long long index = index_sem ? index_sem->sem_to_long(ok) : FULLARRAY;
if (index_sem)
delete index_sem;
if (!ok)
index = FULLARRAY;
return postinc(typ, varname, nelt, index, nlppp);
}

long long Arun::postdec(int typ, _TCHAR *varname, int nelt,
RFASem *index_sem, Nlppp *nlppp)
{
bool ok = false;
long long index = index_sem ? index_sem->sem_to_long(ok) : FULLARRAY;
if (index_sem)
delete index_sem;
if (!ok)
index = FULLARRAY;
return postdec(typ, varname, nelt, index, nlppp);
}

/********************************************
* FN: SORTVALS
* CR: 06/04/00 AM.
Expand Down
30 changes: 30 additions & 0 deletions lite/iexpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3242,6 +3242,21 @@ switch (type_)
ok = false;
goto done;
}
if (index >= 0) // x[i]++ : the indexed element.
{
if (!Arun::bump_arg(Arun::index_arg(pair, index), 1, num))
{
ruleError(line_,nlppp);
nlppp->parse_->line_ = line_;
std::_t_strstream gerrStr;
gerrStr << _T("[inc: Error. Bad type.]") << std::ends;
nlppp->parse_->errOut(&gerrStr,false);
ok = false;
goto done;
}
val = new RFASem(num); // The value before the change.
goto done;
}
Delt<Iarg> *darg;
Iarg *arg;
if (!vals || !(darg = vals->getFirst()))
Expand Down Expand Up @@ -3303,6 +3318,21 @@ switch (type_)
ok = false;
goto done;
}
if (index >= 0) // x[i]-- : the indexed element.
{
if (!Arun::bump_arg(Arun::index_arg(pair, index), -1, num))
{
ruleError(line_,nlppp);
nlppp->parse_->line_ = line_;
std::_t_strstream gerrStr;
gerrStr << _T("[dec: Error. Bad type.]") << std::ends;
nlppp->parse_->errOut(&gerrStr,false);
ok = false;
goto done;
}
val = new RFASem(num); // The value before the change.
goto done;
}
if (!vals || !(darg = vals->getFirst()))
{
// Variable has no value. Set to -1 and done.
Expand Down
2 changes: 1 addition & 1 deletion nlp/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ All rights reserved.
#include "lite/nlp_engine.h"
#include "version.h"

#define NLP_ENGINE_VERSION "4.2.23"
#define NLP_ENGINE_VERSION "4.2.24"

bool cmdReadArgs(int, _TCHAR *argv[], _TCHAR *&, _TCHAR *&, _TCHAR *&, _TCHAR *&, bool &, bool &, bool &, bool &, bool &, bool &, int &, bool &);
void cmdHelpargs(_TCHAR *);
Expand Down
Loading