Exemplo n.º 1
0
/*
**    GenList() reads a list of generators.  The list of generators may
**    consist of abstract generators and identical generators.  Identical
**    generators are used to specify identical relations.
**
**    The defining rules are:
**
**    genlist:         'empty' | genseq | genseq ; genseq
**    genseq:          'generator' | 'generator' ',' genseq
*/
static int      GenList(void) {

	int     nrgens = 0;

	if (Token != GEN) return nrgens;

	nrgens++;
	if (GenNumber(Gen, CREATE) == (gen)0)
		SyntaxError("Duplicate generator");
	NextToken();
	while (Token == COMMA) {
		NextToken();
		if (Token != GEN) SyntaxError("Generator expected");
		nrgens++;
		if (GenNumber(Gen, CREATE) == (gen)0)
			SyntaxError("Duplicate generator");
		NextToken();
	}

	return nrgens;
}
Exemplo n.º 2
0
/*
**    Atom() reads an atom. Note that Atom() creates a generator by
**    calling GenNumber().
**
**    The defining rule for atoms is:
**
**    atom:            'generator' | '(' word ')' | commutator
*/
static node     *Atom(void) {

	node            *n = 0;

	if (Token == GEN) {
		n = GetNode(TGEN);
		n->cont.g = GenNumber(Gen, NOCREATE);
		if (n->cont.g == (gen)0) SyntaxError("Unkown generator");
		NextToken();
	} else if (Token == LPAREN) {
		NextToken();
		n = Word();
		if (Token != RPAREN)
			SyntaxError("Closing parenthesis expected");
		NextToken();
	} else if (Token == LBRACK) {
		n = Commutator();
	} else {
		SyntaxError("Generator, left parenthesis or commutator expected");
	}
	return n;
}
Exemplo n.º 3
0
void Compiler::ParseToByNumberDo(int toPointer, Oop oopNumber, bool bNegativeStep)
{
	PushOptimizedScope();
	
	// Add an "each". This should be at the top of the temporary stack as it is taken over by the do: block
	TempVarRef* pEachTempRef = AddOptimizedTemp(eachTempName);
	
	// Start to generate bytecodes

	// First we must store that from value into our 'each' counter variable/argument. This involves
	// stepping back a bit ...
	_ASSERTE(toPointer < m_codePointer);
	int currentPos = m_codePointer;
	m_codePointer = toPointer;
	// Note we store so leaving the value on the stack as the result of the whole expression
	GenStoreTemp(pEachTempRef);
	m_codePointer = currentPos + m_bytecodes[toPointer].instructionLength();
	
	// Dup the to: value
	GenDup();
	// And push the from value
	GenPushTemp(pEachTempRef);

	// We must jump over the block to the test first time through
	int jumpOver = GenJumpInstruction(LongJump);

	int loopHead = m_codePointer;

	// Parse the one argument block.
	// Leave nothing on the stack, expect 1 argument
	ParseOptimizeBlock(1);

	// Pop off the result of the optimized block
	GenPopStack();
	
	GenDup();
	GenPushTemp(pEachTempRef);
	// If the step is 1/-1, this will be optimised down to Increment/Decrement
	GenNumber(oopNumber, LastTokenRange());
	int add = GenInstruction(SendArithmeticAdd);
	int store = GenStoreTemp(pEachTempRef);

	int comparePointer = m_codePointer;
	
	if (bNegativeStep)
		GenInstruction(SendArithmeticGT);
	else
		// Note that < is the best message to send, since it is normally directly implemented
		GenInstruction(SendArithmeticLT);

	GenJump(LongJumpIfFalse, loopHead);

	// Pop the to: value
	GenPopStack();

	SetJumpTarget(jumpOver, comparePointer);

	TODO("Is this in the right place? What is the last real IP of the loop");
	PopOptimizedScope(ThisTokenRange().m_stop);
	NextToken();
}