Esempio n. 1
0
pgsOperand pgsString::pgs_plus(const pgsVariable &rhs) const
{
	if (rhs.is_string())
	{
		return pnew pgsString(m_data + rhs.value());
	}
	else
	{
		throw pgsArithmeticException(m_data, rhs.value());
	}
}
Esempio n. 2
0
bool pgsRecord::newline()
{
	// Insert a line
	m_record.Add(pgsVectorRecordLine());
	// Initialize each column of the line with an empty string
	for (USHORT i = 0; i < count_columns(); i++)
	{
		m_record.Last().Add(pnew pgsString(wxT("")));
	}
	return true;
}
Esempio n. 3
0
pgsOperand pgsRecord::get(const USHORT &line,
                          const USHORT &column) const
{
	if (line < count_lines() && column < count_columns())
	{
		return m_record[line][column];
	}
	else
	{
		return pnew pgsString(wxT(""));
	}
}
Esempio n. 4
0
pgsOperand pgsIdent::eval(pgsVarMap &vars) const
{
	if (vars.find(m_name) != vars.end())
	{
		return vars[m_name];
	}
	else if (m_name == m_now)
	{
		time_t now = wxDateTime::GetTimeNow();
		return pnew pgsNumber(wxString() << now);
	}
	else
	{
		return pnew pgsString(wxT(""));
	}
}
Esempio n. 5
0
pgsOperand pgsIdentRecord::eval(pgsVarMap &vars) const
{
	// Check whether the variable is a record
	if (vars.find(m_name) != vars.end() && vars[m_name]->is_record())
	{
		// Get the operand as a record
		const pgsRecord &rec = dynamic_cast<const pgsRecord &>(*vars[m_name]);

		// Evaluate parameters
		pgsOperand line(m_line->eval(vars));
		if (line->is_integer())
		{
			long aux_line;
			line->value().ToLong(&aux_line);

			if (m_column != 0)
			{
				pgsOperand column(m_column->eval(vars));
				if (column->is_integer())
				{
					long aux_column;
					column->value().ToLong(&aux_column);
					return rec.get(aux_line, aux_column);
				}
				else if (column->is_string())
				{
					return rec.get(aux_line, rec.get_column(column->value()));
				}
			}
			else
			{
				return rec.get_line(aux_line);
			}
		}
	}

	return pnew pgsString(wxT(""));
}
Esempio n. 6
0
pgsString pgsRecord::string() const
{
	return pgsString(value());
}
Esempio n. 7
0
pgsVariable *pgsString::clone() const
{
	return pnew pgsString(*this);
}
Esempio n. 8
0
pgsString pgsString::string() const
{
	return pgsString(*this);
}
Esempio n. 9
0
pgsOperand pgsExecute::eval(pgsVarMap &vars) const
{
	// Copy statement locally
	wxString stmt(m_query);

	// Build regular expressions
	wxRegEx identifier(wxT("([^\\])(@[a-zA-Z0-9_#@]+)"));
	wxRegEx escaped(wxT("\\\\(@|\\\\)")); // Backslash followed by @ or backslash
	wxASSERT(identifier.IsValid() && escaped.IsValid());

	// Replace variables in statement
	while (identifier.Matches(stmt))
	{
		wxString var = identifier.GetMatch(stmt, 2);
		wxString chr = identifier.GetMatch(stmt, 1);
		if (vars.find(var) != vars.end())
		{
			wxString res = vars[var]->eval(vars)->value();
			identifier.ReplaceFirst(&stmt, chr + pgsUtilities::escape_quotes(res));
		}
		else
		{
			identifier.ReplaceFirst(&stmt, chr + wxT("\\\\") + var);
		}
	}
	escaped.ReplaceAll(&stmt, wxT("\\1"));

	// Perform operations only if we have a valid connection
	if (m_app != 0 && m_app->connection() != 0 && !m_app->TestDestroy())
	{
		pgQueryThread thread(m_app->connection(), stmt);

		if (thread.Create() == wxTHREAD_NO_ERROR)
		{
			if (thread.Run() == wxTHREAD_NO_ERROR)
			{
				while (true)
				{
					if (m_app->TestDestroy()) // wxThread::TestDestroy()
					{
						thread.Delete();
						break;
					}
					else if (thread.IsRunning())
					{
						m_app->Yield();
						m_app->Sleep(20);
					}
					else
					{
						thread.Wait();
						break;
					}
				}

				if (thread.ReturnCode() != PGRES_COMMAND_OK
				        && thread.ReturnCode() != PGRES_TUPLES_OK)
				{
					if (m_cout != 0)
					{
						m_app->LockOutput();

						(*m_cout) << PGSOUTWARNING;
						wxString message(stmt + wxT("\n") + thread
						                 .GetMessagesAndClear().Strip(wxString::both));
						wxRegEx multilf(wxT("(\n)+"));
						multilf.ReplaceAll(&message, wxT("\n"));
						message.Replace(wxT("\n"), wxT("\n")
						                + generate_spaces(PGSOUTWARNING.Length()));
						(*m_cout) << message << wxT("\n");

						m_app->UnlockOutput();
					}
				}
				else if (!m_app->TestDestroy())
				{
					if (m_cout != 0)
					{
						m_app->LockOutput();

						(*m_cout) << PGSOUTQUERY;
						wxString message(thread.GetMessagesAndClear()
						                 .Strip(wxString::both));
						if (!message.IsEmpty())
							message = stmt + wxT("\n") + message;
						else
							message = stmt;
						wxRegEx multilf(wxT("(\n)+"));
						multilf.ReplaceAll(&message, wxT("\n"));
						message.Replace(wxT("\n"), wxT("\n")
						                + generate_spaces(PGSOUTQUERY.Length()));
						(*m_cout) << message << wxT("\n");

						m_app->UnlockOutput();
					}

					pgsRecord *rec = 0;

					if (thread.DataValid())
					{
						pgSet *set = thread.DataSet();
						set->MoveFirst();
						rec = pnew pgsRecord(set->NumCols());
						wxArrayLong columns_int; // List of columns that contain integers
						wxArrayLong columns_real; // List of columns that contain reals
						for (long i = 0; i < set->NumCols(); i++)
						{
							rec->set_column_name(i, set->ColName(i));
							wxString col_type = set->ColType(i);
							if (!col_type.CmpNoCase(wxT("bigint"))
							        || !col_type.CmpNoCase(wxT("smallint"))
							        || !col_type.CmpNoCase(wxT("integer")))
							{
								columns_int.Add(i);
							}
							else if (!col_type.CmpNoCase(wxT("real"))
							         || !col_type.CmpNoCase(wxT("double precision"))
							         || !col_type.CmpNoCase(wxT("money"))
							         || !col_type.CmpNoCase(wxT("numeric")))
							{
								columns_real.Add(i);
							}
						}
						size_t line = 0;
						while (!set->Eof())
						{
							for (long i = 0; i < set->NumCols(); i++)
							{
								wxString value = set->GetVal(i);

								if (columns_int.Index(i) != wxNOT_FOUND
								        && pgsNumber::num_type(value) == pgsNumber::pgsTInt)
								{
									rec->insert(line, i, pnew pgsNumber(value, pgsInt));
								}
								else if (columns_real.Index(i) != wxNOT_FOUND
								         && pgsNumber::num_type(value) == pgsNumber::pgsTReal)
								{
									rec->insert(line, i, pnew pgsNumber(value, pgsReal));
								}
								else
								{
									rec->insert(line, i, pnew pgsString(value));
								}
							}
							set->MoveNext();
							++line;
						}
					}
					else
					{
						rec = pnew pgsRecord(1);
						rec->insert(0, 0, pnew pgsNumber(wxT("1")));
					}

					return rec;
				}
			}
			else
			{
				wxLogError(wxT("PGSCRIPT: Cannot run query thread for the query:\n%s"),
				           m_query.c_str());
			}
		}
		else
		{
			wxLogError(wxT("PGSCRIPT: Cannot create query thread for the query:\n%s"),
			           m_query.c_str());
		}
	}

	// This must return a record whatever happens
	return pnew pgsRecord(1);
}
Esempio n. 10
0
pgsOperand pgsString::pgs_not() const
{
	wxString data = m_data.Strip(wxString::both);
	return pnew pgsString(data.IsEmpty() ? wxT("1") : wxT(""));
}
Esempio n. 11
0
void pgsTestSuite::test_expression_record(void)
{
	pgsVarMap vars;

	pgsStmtList * SL1 = 0;

	wxArrayString columns;
	SL1 = pnew pgsStmtList(pgsTestClass::get_cout());

	{
		columns.Add(wxT("a"));
		columns.Add(wxT("b"));
		columns.Add(wxT("c"));
		columns.Add(wxT("d"));
	}

	// r := { a, b, c, d }
	{
		pgsStmt * S = 0;
		S = pnew pgsDeclareRecordStmt(wxT("r"), columns);
		SL1->insert_back(S);
	}

	// r[2][a] := 5
	{
		pgsStmt * S = 0;
		S = pnew pgsExpressionStmt(pnew pgsAssignToRecord(wxT("r"),
				pnew pgsNumber(wxT("2")), pnew pgsString(wxT("a")),
				pnew pgsNumber(wxT("5"))));
		SL1->insert_back(S);
	}

	// r[1][b] := "abc"
	{
		pgsStmt * S = 0;
		S = pnew pgsExpressionStmt(pnew pgsAssignToRecord(wxT("r"),
				pnew pgsNumber(wxT("1")), pnew pgsString(wxT("b")),
				pnew pgsString(wxT("abc"))));
		SL1->insert_back(S);
	}

	// r[0][0] := 1
	{
		pgsStmt * S = 0;
		S = pnew pgsExpressionStmt(pnew pgsAssignToRecord(wxT("r"),
				pnew pgsNumber(wxT("0")), pnew pgsNumber(wxT("0")),
				pnew pgsNumber(wxT("1"))));
		SL1->insert_back(S);
	}

	// w := r
	{
		pgsStmt * S = 0;
		S = pnew pgsExpressionStmt(pnew pgsAssign(wxT("w"),
				pnew pgsIdent(wxT("r"))));
		SL1->insert_back(S);
	}

	// p = (r != w)
	{
		pgsStmt * S = 0;
		S = pnew pgsExpressionStmt(pnew pgsAssign(wxT("p"),
				pnew pgsDifferent(pnew pgsIdent(wxT("r")),
				pnew pgsIdent(wxT("w")))));
		SL1->insert_back(S);
	}

	// r.remove_line(1)
	{
		pgsStmt * S = 0;
		S = pnew pgsExpressionStmt(pnew pgsRemoveLine(wxT("r"),
				pnew pgsNumber(wxT("1"))));
		TS_ASSERT(pgsRemoveLine(wxT("r"), pnew pgsNumber(wxT("1")))
				.value() == wxT("RMLINE(r[1])"));
		SL1->insert_back(S);
	}

	// q = (r != w)
	{
		pgsStmt * S = 0;
		S = pnew pgsExpressionStmt(pnew pgsAssign(wxT("q"),
				pnew pgsDifferent(pnew pgsIdent(wxT("r")),
				pnew pgsIdent(wxT("w")))));
		SL1->insert_back(S);
	}

	// o = (r < w)
	{
		pgsStmt * S = 0;
		S = pnew pgsExpressionStmt(pnew pgsAssign(wxT("o"),
				pnew pgsLower(pnew pgsIdent(wxT("r")),
				pnew pgsIdent(wxT("w")))));
		SL1->insert_back(S);
	}

	SL1->eval(vars);

	// Test symbol table at the end of the execution
	TS_ASSERT(vars[wxT("p")]->value() == wxT("0"));
	TS_ASSERT(vars[wxT("q")]->value() == wxT("1"));
	TS_ASSERT(vars[wxT("o")]->value() == wxT("1"));

	pdelete(SL1);
}
Esempio n. 12
0
pgsOperand pgsTrim::eval(pgsVarMap &vars) const
{
	return pnew pgsString(m_exp->eval(vars)->value().Strip(wxString::both));
}
Esempio n. 13
0
pgsString pgsNumber::string() const
{
	return pgsString(m_data);
}
Esempio n. 14
0
void pgsTestSuite::test_object_variable(void)
{
	// A check is done when a pgsNumber is assigned to verify whether it is
	// a valid number. Default is an integer otherwise pgsReal must be
	// specified as second parameter of the constructor
	// pgsString does not perform any check but does not authorize arithmetic
	// on it even if it stores a number
	
	// Test string type
	{
		pgsString a(wxT("test"));
		TS_ASSERT(a.is_string() && !a.is_number() && !a.is_record());
		pgsString b(wxT("123456."));
		TS_ASSERT(b.is_string() && !b.is_number() && !b.is_record());
		pgsString c(wxT("423432"));
		TS_ASSERT(c.is_string() && !c.is_number() && !c.is_record());
		pgsString d(wxT("+.644e5"));
		TS_ASSERT(d.is_string() && !d.is_number() && !d.is_record());
		pgsString e(wxT("0x0"));
		TS_ASSERT(e.is_string() && !e.is_number() && !e.is_record());
	}

	// Test number type
	{
		pgsNumber a(wxT("123456."), pgsReal);
		TS_ASSERT(a.is_real() && !a.is_string() && !a.is_record());
		pgsNumber b(wxT("423432"));
		TS_ASSERT(b.is_integer() && !b.is_string() && !b.is_record());
		pgsNumber c(wxT("+.644e5"), pgsReal);
		TS_ASSERT(c.is_real() && !c.is_string() && !c.is_record());
	}

	// Test integers
	{
		for (int i = 1; i <= 100; i++)
		{
			// [1] Generate a random integer as a string
			wxString str_rnd;
			for (int j = 0; j < i; j++)
			{
				char c = rand() % 9 + 48;
				str_rnd << c;
			}
			
			// [2] Allocate a number and test type properties
			pgsNumber exp(str_rnd);
			TS_ASSERT(exp.value() == str_rnd);
			TS_ASSERT(exp.is_number() && !exp.is_string() && !exp.is_record());
			TS_ASSERT(exp.is_integer() && !exp.is_real());
			
			// [3] Test copy constructor
			pgsNumber copy(exp);
			TS_ASSERT(copy.value() == exp.value() && copy.is_integer());
			
			// [4] Test assignment operator
			exp = pgsNumber(wxT("1") + str_rnd, pgsReal);
			TS_ASSERT(exp.is_number() && !exp.is_string() && !exp.is_record());
			TS_ASSERT(!exp.is_integer() && exp.is_real());
		}
	}

	// Test reals
	{
		for (int i = 2; i <= 16; i++)
		{
			// [1] Generate a random real as a string
			wxString str_rnd;
			for (int j = 0; j < i / 2; j++)
			{
				char c = rand() % 9 + 48;
				str_rnd << c;
			}
			str_rnd << wxT(".");
			for (int j = 0; j < i / 2; j++)
			{
				char c = rand() % 9 + 48;
				str_rnd << c;
			}
			
			// [2] Allocate a number and test type properties
			pgsNumber exp(str_rnd, pgsReal);
			TS_ASSERT(exp.is_number() && !exp.is_string() && !exp.is_record());
			TS_ASSERT(!exp.is_integer() && exp.is_real());
			
			// [3] Test copy constructor
			pgsNumber copy(exp);
			TS_ASSERT(copy.value() == exp.value() && copy.is_real());
			
			// [4] Test assignment operator
			exp = pgsNumber(wxT("1") + str_rnd, pgsReal);
			TS_ASSERT(exp.is_number() && !exp.is_string() && !exp.is_record());
			TS_ASSERT(!exp.is_integer() && exp.is_real());
		}
	}

	// Test real
	{
		pgsNumber exp(wxT("+1.5e-300000000000657788"), pgsReal);
		TS_ASSERT(exp.is_real() && !exp.is_integer() && !exp.is_string());
	}

	// Test real
	{
		pgsNumber exp(wxT("-1.e+0"), pgsReal);
		TS_ASSERT(exp.is_real() && !exp.is_integer() && !exp.is_string());
	}

	// Test real
	{
		pgsNumber exp(wxT("+.0e-1"), pgsReal);
		TS_ASSERT(exp.is_real() && !exp.is_integer() && !exp.is_string());
	}

	// Test real
	{
		pgsNumber exp(wxT("-0.0E5"), pgsReal);
		TS_ASSERT(exp.is_real() && !exp.is_integer() && !exp.is_string());
	}

	// Test real
	{
		pgsNumber exp(wxT("0."), pgsReal);
		TS_ASSERT(exp.is_real() && !exp.is_integer() && !exp.is_string());
	}

	// Test real
	{
		pgsNumber exp(wxT(".1234567890098765432"), pgsReal);
		TS_ASSERT(exp.is_real() && !exp.is_integer() && !exp.is_string());
	}

	// Test string
	{
		pgsString exp(wxT("."));
		TS_ASSERT(!exp.is_real() && !exp.is_integer() && exp.is_string());
	}

	// Test string
	{
		pgsString exp(wxT(""));
		TS_ASSERT(!exp.is_real() && !exp.is_integer() && exp.is_string());
	}

	// Test string
	{
		pgsString exp(wxT("e5"));
		TS_ASSERT(!exp.is_real() && !exp.is_integer() && exp.is_string());
	}

	// Test real
	{
		pgsNumber exp(wxT("0e0"), pgsReal);
		TS_ASSERT(exp.is_real() && !exp.is_integer() && !exp.is_string());
	}

	// Test real
	{
		pgsNumber exp(wxT("100000000000000000e1"), pgsReal);
		TS_ASSERT(exp.is_real() && !exp.is_integer() && !exp.is_string());
	}

	// Test string
	{
		pgsString exp(wxT("100000000000000000e"));
		TS_ASSERT(!exp.is_real() && !exp.is_integer() && exp.is_string());
	}

	// Test some operations
	{
		pgsVariable * a = pnew pgsNumber(wxT("123."), pgsReal);
		pgsVariable * b = pnew pgsNumber(wxT("2"), pgsInt);
		pgsVariable * c = pnew pgsString(wxT("0x1"));
		
		pgsVarMap vars;
		
		// 123. + 2 gives 125
		pgsPlus * d = 0;
		d = pnew pgsPlus(a, b); // Deletes a and b		
		pgsOperand v = d->eval(vars);
		TS_ASSERT(v->value() == wxT("125") && v->is_real());
		
		// (123. + 2) + 0x1 gives the concatenation of the strings
		pgsPlus * e = 0;
		e = pnew pgsPlus(d, c); // Deletes d and c
		try
		{
			e->eval(vars);
			TS_ASSERT(false);
		}
		catch (const pgsArithmeticException &)
		{
			
		}
		
		// Test copy
		pgsPlus f(*e); // f is automatically deleted
		pdelete(e); // Deletes e
	}
}
Esempio n. 15
0
void pgsTestSuite::test_statement_stmt(void)
{
	// Symbol table
	pgsVarMap vars;

	// Test Assignment Statement
	{
		pgsStmt * S1 = 0, * S2 = 0, * S3 = 0;

		// x := 0
		S1 = pnew pgsExpressionStmt(pnew pgsAssign(wxT("x"),
				pnew pgsNumber(wxT("0"), pgsInt)));
		S1->eval(vars);
		
		// y := 2
		S2 = pnew pgsExpressionStmt(pnew pgsAssign(wxT("y"),
				pnew pgsNumber(wxT("2"), pgsInt)));
		S2->eval(vars);

		// Check that assignments went fine
		TS_ASSERT(vars[wxT("x")]->value() == wxT("0"));
		TS_ASSERT(vars[wxT("y")]->value() == wxT("2"));

		// x := 1
		S3 = pnew pgsExpressionStmt(pnew pgsAssign(wxT("x"),
				pnew pgsNumber(wxT("1"), pgsInt)));
		S3->eval(vars);

		TS_ASSERT(vars[wxT("x")]->value() == wxT("1"));
		TS_ASSERT(vars[wxT("y")]->value() == wxT("2"));

		pdelete(S1);
		pdelete(S2);
		pdelete(S3);
	}

	// Test If Statement (if 0 then z := 0 else z := 1 fi)
	{
		pgsStmt * S1 = 0;
		pgsStmtList * SL1 = 0, * SL2 = 0;

		// z := 0
		SL1 = pnew pgsStmtList(pgsTestClass::get_cout());
		SL1->insert_front(pnew pgsExpressionStmt(pnew pgsAssign(wxT("z"),
				pnew pgsNumber(wxT("0"), pgsInt))));
		
		// z := 1
		SL2 = pnew pgsStmtList(pgsTestClass::get_cout());
		SL2->insert_front(pnew pgsExpressionStmt(pnew pgsAssign(wxT("z"),
				pnew pgsNumber(wxT("1"), pgsInt))));

		// if 0 then z := 0 else z := 1 fi
		S1 = pnew pgsIfStmt(pnew pgsNumber(wxT("0"), pgsInt), SL1, SL2);
		S1->eval(vars);

		TS_ASSERT(vars[wxT("x")]->value() == wxT("1"));
		TS_ASSERT(vars[wxT("y")]->value() == wxT("2"));
		TS_ASSERT(vars[wxT("z")]->value() == wxT("1"));

		pdelete(S1);
	}

	// Test If Statement (if 1 then z := 0 else z := 1 fi)
	{
		pgsStmt * S1 = 0;
		pgsStmtList * SL1 = 0, * SL2 = 0;

		// z := 0
		SL1 = pnew pgsStmtList(pgsTestClass::get_cout());
		SL1->insert_front(pnew pgsExpressionStmt(pnew pgsAssign(wxT("z"),
				pnew pgsNumber(wxT("0"), pgsInt))));
		
		// z := 1
		SL2 = pnew pgsStmtList(pgsTestClass::get_cout());
		SL2->insert_front(pnew pgsExpressionStmt(pnew pgsAssign(wxT("z"),
				pnew pgsNumber(wxT("1"), pgsInt))));

		// if 1 then z := 0 else z := 1 fi
		S1 = pnew pgsIfStmt(pnew pgsNumber(wxT("1"), pgsInt), SL1, SL2);
		S1->eval(vars);

		TS_ASSERT(vars[wxT("x")]->value() == wxT("1"));
		TS_ASSERT(vars[wxT("y")]->value() == wxT("2"));
		TS_ASSERT(vars[wxT("z")]->value() == wxT("0"));

		pdelete(S1);
	}
	
	// Test While Statement (while i do s := s + i; i := i-1 done)
	{
		pgsStmt * S1 = 0, * S2 = 0, * S3 = 0;
		pgsStmtList * SL1 = 0;

		// i := 3
		pgsExpressionStmt(pnew pgsAssign(wxT("i"), pnew pgsNumber(wxT("3"),
				pgsInt))).eval(vars);
		
		// s := 0
		pgsExpressionStmt(pnew pgsAssign(wxT("s"), pnew pgsNumber(wxT("0"),
				pgsInt))).eval(vars);

		TS_ASSERT(vars[wxT("x")]->value() == wxT("1"));
		TS_ASSERT(vars[wxT("y")]->value() == wxT("2"));
		TS_ASSERT(vars[wxT("z")]->value() == wxT("0"));
		TS_ASSERT(vars[wxT("i")]->value() == wxT("3"));
		TS_ASSERT(vars[wxT("s")]->value() == wxT("0"));
		TS_ASSERT(vars.size() == 5);
		
		// i == 3 ?
		TS_ASSERT(pgsIdent(wxT("i")).eval(vars)->value() == wxT("3"));
		// s + i == 3 ?
		TS_ASSERT(pgsPlus(pnew pgsIdent(wxT("s")),
				pnew pgsIdent(wxT("i"))).eval(vars)->value() == wxT("3"));
		
		// s := s + i
		S1 = pnew pgsExpressionStmt(pnew pgsAssign(wxT("s"),
				pnew pgsPlus(pnew pgsIdent(wxT("s")),
						pnew pgsIdent(wxT("i")))));
		// i := i-1
		S2 = pnew pgsExpressionStmt(pnew pgsAssign(wxT("i"),
				pnew pgsMinus(pnew pgsIdent(wxT("i")),
						pnew pgsNumber(wxT("1"), pgsInt))));
		SL1 = pnew pgsStmtList(pgsTestClass::get_cout());
		SL1->insert_front(S2);
		SL1->insert_front(S1);

		// while i do s := s + i; i := i-1 done
		S3 = pnew pgsWhileStmt(pnew pgsIdent(wxT("i")), SL1);
		S3->eval(vars);
		pdelete(S3);

		TS_ASSERT(vars[wxT("x")]->value() == wxT("1"));
		TS_ASSERT(vars[wxT("y")]->value() == wxT("2"));
		TS_ASSERT(vars[wxT("z")]->value() == wxT("0"));
		TS_ASSERT(vars[wxT("i")]->value() == wxT("0"));
		TS_ASSERT(vars[wxT("s")]->value() == wxT("6"));
		TS_ASSERT(vars.size() == 5);
	}
	
	// Test While Statement
	// while i < 10 do
	//   i := i + i;
	//   if i > 5 then
	//     break;
	//   else
	//     continue;
	//     s := s + 1;
	//   fi
	// done
	{
		pgsStmt * S1 = 0, * S2 = 0, * S3 = 0, * S4 = 0;
		pgsStmtList * SL1 = 0, * SL2 = 0;

		// i := 0
		pgsExpressionStmt(pnew pgsAssign(wxT("i"), pnew pgsNumber(wxT("0"),
				pgsInt))).eval(vars);
		
		// s := 5
		pgsExpressionStmt(pnew pgsAssign(wxT("s"), pnew pgsNumber(wxT("5"),
				pgsInt))).eval(vars);

		TS_ASSERT(vars[wxT("i")]->value() == wxT("0"));
		TS_ASSERT(vars[wxT("s")]->value() == wxT("5"));
		
		// i := i + 1
		S1 = pnew pgsExpressionStmt(pnew pgsAssign(wxT("i"),
				pnew pgsPlus(pnew pgsIdent(wxT("i")),
						pnew pgsNumber(wxT("1"), pgsInt))));
		
		// s := s + 1
		S2 = pnew pgsExpressionStmt(pnew pgsAssign(wxT("s"),
				pnew pgsPlus(pnew pgsIdent(wxT("s")),
						pnew pgsNumber(wxT("1"), pgsInt))));

		// s := s + 1; continue
		SL2 = pnew pgsStmtList(pgsTestClass::get_cout());
		SL2->insert_back(pnew pgsContinueStmt());
		SL2->insert_back(S2);
		
		// if i > 5 ... fi
		S3 = pnew pgsIfStmt(pnew pgsGreater(pnew pgsIdent(wxT("i")),
				pnew pgsNumber(wxT("5"))), pnew pgsBreakStmt(), SL2);

		// while ... done
		SL1 = pnew pgsStmtList(pgsTestClass::get_cout());
		SL1->insert_back(S1);
		SL1->insert_back(S3);
		S4 = pnew pgsWhileStmt(pnew pgsLower(pnew pgsIdent(wxT("i")),
				pnew pgsNumber(wxT("10"))), SL1);
		S4->eval(vars);
		pdelete(S4);

		TS_ASSERT(vars[wxT("i")]->value() == wxT("6"));
		TS_ASSERT(vars[wxT("s")]->value() == wxT("5"));
	}

	// Test Assign Statement with a generator
	{
		pgsExpression * N0 = 0, * N1 = 0, * N2 = 0;
		pgsStmt * S1 = 0, * S2 = 0, * S3 = 0;

		// m := -10
		pgsExpressionStmt(pnew pgsAssign(wxT("m"),
				pnew pgsNumber(wxT("-10")))).eval(vars);

		// integer(m, 10, true, now)
		N0 = pnew pgsGenInt(pnew pgsIdent(wxT("m")), pnew pgsNumber(wxT("10")),
				pnew pgsNumber(wxT("1")), pnew pgsNumber(wxString()
						<< wxDateTime::GetTimeNow()));
		// string(1, 10, 2, now)
		N1 = pnew pgsGenString(pnew pgsNumber(wxT("1")),
				pnew pgsNumber(wxT("10")), pnew pgsNumber(wxT("2")),
						pnew pgsNumber(wxString() << wxDateTime::GetTimeNow()));
		// regex(a{2}[a-zA-Z]{10}c{3}, now)
		N2 = pnew pgsGenRegex(pnew pgsString(wxT("a{2}[a-zA-Z]{10}c{3}")),
						pnew pgsNumber(wxString() << wxDateTime::GetTimeNow()));

		// x := integer(m, 10, true, now)
		S1 = pnew pgsExpressionStmt(pnew pgsAssign(wxT("x"), N0));
		S1->eval(vars);
		// y := string(1, 10, 2, now)
		S2 = pnew pgsExpressionStmt(pnew pgsAssign(wxT("y"), N1));
		S2->eval(vars);
		// z := regex(a{2}[a-zA-Z]{10}c{3}, now)
		S3 = pnew pgsExpressionStmt(pnew pgsAssign(wxT("z"), N2));
		S3->eval(vars);

		wxString result1, result2, result3;
		wxArrayString sav;
		for (int i = 0; i < 21; i++)
		{
			// Check that x result is unique (we wanted to generate a sequence)
			result1 = pgsIdent(wxT("x")).eval(vars)->value();
			TS_ASSERT(sav.Index(result1) == wxNOT_FOUND);
			sav.Add(result1);
			
			// Check that y result is at least 3 characters (two words of 1
			// character with a space in the middle) and less than 21
			result2 = pgsIdent(wxT("y")).eval(vars)->value();
			TS_ASSERT(result2.Length() >= 3 && result2.Length() <= 21);
			
			// Check the regex-based generators
			result3 = pgsIdent(wxT("z")).eval(vars)->value();
			TS_ASSERT(result3.Length() == 15);
			TS_ASSERT(result3.StartsWith(wxT("aa")) && result3.EndsWith(wxT("ccc")));
		}

		pdelete(S1); // Deletes N0
		pdelete(S2); // Deletes N1
		pdelete(S3); // Deletes N2
	}

	
	// Test an unknown identifier
	{
		pgsExpression * E1;
		
		E1 = pnew pgsIdent(wxT("unknown"));
		TS_ASSERT(E1->eval(vars)->value() == wxT(""));
		
		pdelete(E1);
	}
}
Esempio n. 16
0
pgsRecord pgsString::record() const
{
	pgsRecord *rec = 0;

	// Try to find the representation of a record in the string
	{
		wxString element(wxT("(\"([^\"\\\\]|\\\\.)*\")|((-|[a-zA-Z0-9\\+\\.])+)"));
		wxString data(m_data);
		wxRegEx regex1(wxString() << wxT("^[[:space:]]*\\([[:space:]]*(")
		               << element << wxT(")[[:space:]]*([,][[:space:]]*(")
		               << element << wxT(")[[:space:]]*)*\\)"), wxRE_DEFAULT | wxRE_ICASE);

		// Find each line
		size_t line_nb = 0, nb_of_columns = 0;
		bool count_columns = true;
		while (regex1.Matches(data))
		{
			// Process that line: find each element
			wxString line(regex1.GetMatch(data));
			wxRegEx regex2(element);
			size_t column_nb = 0;
			while (regex2.Matches(line))
			{
				if (count_columns == true)
				{
					++nb_of_columns;
				}
				else
				{
					if (column_nb < nb_of_columns && rec != 0)
					{
						wxString value(regex2.GetMatch(line));
						if (value.StartsWith(wxT("\""))
						        && value.EndsWith(wxT("\"")))
						{
							// This is a string
							value = value.Mid(1, value.Len() - 2);
							value.Replace(wxT("\\\""), wxT("\""));
							value.Replace(wxT("\\\\"), wxT("\\"));
							rec->insert(line_nb, column_nb,
							            pnew pgsString(value));
						}
						else
						{
							// This is a number or a string
							pgsTypes type = pgsNumber::num_type(value);
							switch (type)
							{
								case pgsTInt:
									rec->insert(line_nb, column_nb,
									            pnew pgsNumber(value, pgsInt));
									break;
								case pgsTReal:
									rec->insert(line_nb, column_nb,
									            pnew pgsNumber(value, pgsReal));
									break;
								default:
									rec->insert(line_nb, column_nb,
									            pnew pgsString(value));
									break;
							}
						}
					}
					++column_nb;
				}

				regex2.ReplaceFirst(&line, wxT(""));
			}

			// If it is the first loop we want to process this line a
			// second time because the first one was meant to count
			// the number of columns
			if (count_columns == true)
			{
				count_columns = false;
				rec = pnew pgsRecord(nb_of_columns);
			}
			else
			{
				regex1.ReplaceFirst(&data, wxT(""));
				++line_nb;
			}
		}
	}

	// Process the case
	if (rec == 0)
	{
		rec = pnew pgsRecord(1);
		rec->insert(0, 0, this->clone());
	}

	pgsRecord ret_val(*rec);
	pdelete(rec);
	return ret_val;
}
Esempio n. 17
0
void pgsTestSuite::test_operator_number(void)
{
	// From a number with a string
	{
		// [1] Create variables
		pgsVariable * var0 = 0;
		var0 = pnew pgsNumber(wxT("100"));
		pgsVariable * var1 = 0;
		var1 = pnew pgsString(wxT("5"));
		
		// [2] Addition
		try
		{
			(*var0 + *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [3] Subtraction
		try
		{
			(*var0 - *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [4] Multiplication
		try
		{
			(*var0 * *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [5] Division
		try
		{
			(*var0 / *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [6] Modulo
		try
		{
			(*var0 % *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [9] Equal
		try
		{
			(*var0 == *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [10] Different
		try
		{
			(*var0 != *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [11] Lower
		try
		{
			(*var0 < *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [12] Greater
		try
		{
			(*var0 > *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [13] Lower or equal
		try
		{
			(*var0 <= *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [14] Greater or equal
		try
		{
			(*var0 >= *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [15] Not
		TS_ASSERT((!(*var0))->value() == wxT("0"));
		pgsOperand op(pnew pgsNumber(wxT("0")));
		TS_ASSERT((!(*op))->value() == wxT("1"));
		
		// [16] Almost equal
		try
		{
			(*var0 &= *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [17] Is true?
		TS_ASSERT(var0->pgs_is_true() == true);
		TS_ASSERT((!(*var0))->pgs_is_true() == false);
		
		// [18] Delete variables
		pdelete(var0);
		pdelete(var1);
	}
	
	// From a number (integer) with a real number
	{
		// [1] Create variables
		pgsVariable * var0 = 0;
		var0 = pnew pgsNumber(wxT("100"), pgsInt);
		pgsVariable * var1 = 0;
		var1 = pnew pgsNumber(wxT("5"), pgsReal);
		
		// [2] Addition
		TS_ASSERT((*var0 + *var1)->value() == wxT("105"));
		
		// [3] Subtraction
		TS_ASSERT((*var0 - *var1)->value() == wxT("95"));
		
		// [4] Multiplication
		TS_ASSERT((*var0 * *var1)->value() == wxT("500"));
		
		// [5] Division
		TS_ASSERT((*var0 / *var1)->value() == wxT("20"));
		
		// [6] Modulo
		TS_ASSERT((*var0 % *var1)->value() == wxT("0"));
		
		// [9] Equal
		TS_ASSERT((*var0 == *var1)->value() == wxT("0"));
		
		// [10] Different
		TS_ASSERT((*var0 != *var1)->value() == wxT("1"));
		
		// [11] Lower
		TS_ASSERT((*var0 < *var1)->value() == wxT("0"));
		
		// [12] Greater
		TS_ASSERT((*var0 > *var1)->value() == wxT("1"));
		
		// [13] Lower or equal
		TS_ASSERT((*var0 <= *var1)->value() == wxT("0"));
		
		// [14] Greater or equal
		TS_ASSERT((*var0 >= *var1)->value() == wxT("1"));
		
		// [15] Not
		TS_ASSERT((!(*var0))->value() == wxT("0"));
		
		// [16] Almost equal
		TS_ASSERT((*var0 &= *var1)->value() == wxT("0"));
		
		// [17] Is true?
		TS_ASSERT(var0->pgs_is_true() == true);
		TS_ASSERT((!(*var0))->pgs_is_true() == false);
		
		// [18] Delete variables
		pdelete(var0);
		pdelete(var1);
	}
	
	// From a number with a record
	{
		// [1] Create variables
		pgsVariable * var0 = 0;
		var0 = pnew pgsNumber(wxT("100"));
		pgsRecord * rec = 0;
		rec = pnew pgsRecord(1);
		rec->insert(0, 0, pnew pgsString(wxT("5")));
		pgsVariable * var1 = 0;
		var1 = rec;
		
		// [2] Addition
		try
		{
			(*var0 + *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [3] Subtraction
		try
		{
			(*var0 - *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [4] Multiplication
		try
		{
			(*var0 * *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [5] Division
		try
		{
			(*var0 / *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [6] Modulo
		try
		{
			(*var0 % *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [9] Equal
		try
		{
			(*var0 == *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [10] Different
		try
		{
			(*var0 != *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [11] Lower
		try
		{
			(*var0 < *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [12] Greater
		try
		{
			(*var0 > *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [13] Lower or equal
		try
		{
			(*var0 <= *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [14] Greater or equal
		try
		{
			(*var0 >= *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [15] Not
		TS_ASSERT((!(*var0))->value() == wxT("0"));
		
		// [16] Almost equal
		try
		{
			(*var0 &= *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [17] Is true?
		TS_ASSERT(var0->pgs_is_true() == true);
		TS_ASSERT((!(*var0))->pgs_is_true() == false);
		
		// [18] Delete variables
		pdelete(var0);
		pdelete(var1);
	}
	
	// From a number with a record
	{
		// [1] Create variables
		pgsVariable * var0 = 0;
		var0 = pnew pgsNumber(wxT("100"));
		pgsRecord * rec = 0;
		rec = pnew pgsRecord(1);
		rec->insert(0, 0, pnew pgsNumber(wxT("5")));
		rec->insert(1, 0, pnew pgsNumber(wxT("1")));
		pgsVariable * var1 = 0;
		var1 = rec;
		
		// [2] Addition
		try
		{
			(*var0 + *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [3] Subtraction
		try
		{
			(*var0 - *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [4] Multiplication
		try
		{
			(*var0 * *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [5] Division
		try
		{
			(*var0 / *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [6] Modulo
		try
		{
			(*var0 % *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [9] Equal
		try
		{
			(*var0 == *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [10] Different
		try
		{
			(*var0 != *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [11] Lower
		try
		{
			(*var0 < *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [12] Greater
		try
		{
			(*var0 > *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [13] Lower or equal
		try
		{
			(*var0 <= *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [14] Greater or equal
		try
		{
			(*var0 >= *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [18] Delete variables
		pdelete(var0);
		pdelete(var1);
	}
	
	// From a number with a string generator
	{
		// [1] Create variables
		pgsVariable * var0 = 0;
		var0 = pnew pgsNumber(wxT("100"));
		pgsStringGen * gen = 0;
		gen = pnew pgsStringGen(10, 20);
		pgsVariable * var1 = 0;
		var1 = pnew pgsGenerator(pgsVariable::pgsTString, gen);
		
		// [2] Addition
		try
		{
			(*var0 + *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [3] Subtraction
		try
		{
			(*var0 - *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [4] Multiplication
		try
		{
			(*var0 * *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [5] Division
		try
		{
			(*var0 / *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [6] Modulo
		try
		{
			(*var0 % *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [9] Equal
		try
		{
			(*var0 == *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [10] Different
		try
		{
			(*var0 != *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [11] Lower
		try
		{
			(*var0 < *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [12] Greater
		try
		{
			(*var0 > *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [13] Lower or equal
		try
		{
			(*var0 <= *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [14] Greater or equal
		try
		{
			(*var0 >= *var1);
			TS_ASSERT(false);
		}
		catch (const pgsException &)
		{
			
		}
		
		// [18] Delete variables
		pdelete(var0);
		pdelete(var1);
	}
	
	// From a number with an integer generator
	{
		// [1] Create variables
		pgsVariable * var0 = 0;
		var0 = pnew pgsNumber(wxT("100"));
		pgsIntegerGen * gen = 0;
		gen = pnew pgsIntegerGen(5, 5);
		pgsVariable * var1 = 0;
		var1 = pnew pgsGenerator(pgsVariable::pgsTInt, gen);
		
		// [2] Addition
		TS_ASSERT((*var0 + *var1)->value() == wxT("105"));
		
		// [3] Subtraction
		TS_ASSERT((*var0 - *var1)->value() == wxT("95"));
		
		// [4] Multiplication
		TS_ASSERT((*var0 * *var1)->value() == wxT("500"));
		
		// [5] Division
		TS_ASSERT((*var0 / *var1)->value() == wxT("20"));
		
		// [6] Modulo
		TS_ASSERT((*var0 % *var1)->value() == wxT("0"));
		
		// [9] Equal
		TS_ASSERT((*var0 == *var1)->value() == wxT("0"));
		
		// [10] Different
		TS_ASSERT((*var0 != *var1)->value() == wxT("1"));
		
		// [11] Lower
		TS_ASSERT((*var0 < *var1)->value() == wxT("0"));
		
		// [12] Greater
		TS_ASSERT((*var0 > *var1)->value() == wxT("1"));
		
		// [13] Lower or equal
		TS_ASSERT((*var0 <= *var1)->value() == wxT("0"));
		
		// [14] Greater or equal
		TS_ASSERT((*var0 >= *var1)->value() == wxT("1"));
		
		// [15] Not
		TS_ASSERT((!(*var0))->value() == wxT("0"));
		
		// [16] Almost equal
		TS_ASSERT((*var0 &= *var1)->value() == wxT("0"));
		
		// [17] Is true?
		TS_ASSERT(var0->pgs_is_true() == true);
		TS_ASSERT((!(*var0))->pgs_is_true() == false);
		
		// [18] Delete variables
		pdelete(var0);
		pdelete(var1);
	}
}
pgsVariable * pgsContext::encoding()
{
	pgsVariable * encoding = pnew pgsString(wxLocale::GetSystemEncodingName());
	push_var(encoding);
	return encoding;
}