예제 #1
0
// ----------------------------------------------------------------------------
// TLFunction::addContext
//
// Adds a [context] of the function
// ----------------------------------------------------------------------------
void TLFunction::addContext(
	const string& context,
	const string& args,
	const string& return_type,
	string        description,
	const string& deprecated_f)
{
	contexts_.push_back(Context{ context, {}, return_type, description, "", "", "" });
	auto& ctx = contexts_.back();

	// Parse args
	Tokenizer tz;
	tz.setSpecialCharacters("[],");
	tz.openString(args);

	vector<string> arg_tokens;
	while (true)
	{
		while (!tz.check(","))
		{
			arg_tokens.push_back(tz.current().text);
			if (tz.atEnd())
				break;
			tz.adv();
		}

		ctx.params.push_back({});
		ctx.params.back().parse(arg_tokens);
		arg_tokens.clear();

		if (tz.atEnd())
			break;

		tz.adv();
	}

	if (!deprecated_f.empty())
	{
		// Parse deprecated string
		tz.openString(deprecated_f);

		for (unsigned t = 0; t < 2; t++)
		{
			while (tz.check(","))
				tz.adv();

			bool is_replacement = true;
			for (unsigned c = 0; c < tz.current().text.size(); c++)
			{
				char chr = tz.current().text[c];
				if (isdigit(chr) || chr == '.')
				{
					is_replacement = false;
					break;
				}
			}

			if (is_replacement)
				ctx.deprecated_f = tz.current().text;
			else
				ctx.deprecated_v = tz.current().text;

			if (tz.atEnd())
				break;
			tz.adv();
		}
	}
}
예제 #2
0
// -----------------------------------------------------------------------------
// Parses ZMAPINFO-format definitions in [entry]
// -----------------------------------------------------------------------------
bool MapInfo::parseZMapInfo(ArchiveEntry* entry)
{
	Tokenizer tz;
	tz.setReadLowerCase(true);
	tz.openMem(entry->data(), entry->name());

	while (!tz.atEnd())
	{
		// Include
		if (tz.check("include"))
		{
			// Get entry at include path
			auto include_entry = entry->parent()->entryAtPath(tz.next().text);

			if (!include_entry)
			{
				Log::warning(
					"Warning - Parsing ZMapInfo \"{}\": Unable to include \"{}\" at line {}",
					entry->name(),
					tz.current().text,
					tz.lineNo());
			}
			else if (!parseZMapInfo(include_entry))
				return false;
		}

		// Map
		else if (tz.check("map") || tz.check("defaultmap") || tz.check("adddefaultmap"))
		{
			if (!parseZMap(tz, tz.current().text))
				return false;
		}

		// DoomEdNums
		else if (tz.check("doomednums"))
		{
			if (!parseDoomEdNums(tz))
				return false;
		}

		// Unknown block (skip it)
		else if (tz.check("{"))
		{
			Log::warning(2, "Warning - Parsing ZMapInfo \"{}\": Skipping {{}} block", entry->name());

			tz.adv();
			tz.skipSection("{", "}");
			continue;
		}

		// Unknown
		else
		{
			Log::warning(2, R"(Warning - Parsing ZMapInfo "{}": Unknown token "{}")", entry->name(), tz.current().text);
		}

		tz.adv();
	}

	Log::info(2, "Parsed ZMapInfo entry {} successfully", entry->name());

	return true;
}

// -----------------------------------------------------------------------------
// Parses a ZMAPINFO map definition of [type] beginning at the current token in
// tokenizer [tz]
// -----------------------------------------------------------------------------
bool MapInfo::parseZMap(Tokenizer& tz, std::string_view type)
{
	// TODO: Handle adddefaultmap
	auto map = default_map_;

	// Normal map, get lump/name/etc
	tz.adv();
	if (type == "map")
	{
		// Entry name should be just after map keyword
		map.entry_name = tz.current().text;

		// Parse map name
		tz.adv();
		if (tz.check("lookup"))
		{
			map.lookup_name = true;
			map.name        = tz.next().text;
		}
		else
		{
			map.lookup_name = false;
			map.name        = tz.current().text;
		}

		tz.adv();
	}

	if (!tz.advIf("{"))
	{
		Log::error(R"(Error Parsing ZMapInfo: Expecting "{{", got "{}" at line {})", tz.current().text, tz.lineNo());
		return false;
	}

	while (!tz.checkOrEnd("}"))
	{
		// Block (skip it)
		if (tz.advIf("{"))
			tz.skipSection("{", "}");

		// LevelNum
		else if (tz.check("levelnum"))
		{
			if (!checkEqualsToken(tz, "ZMapInfo"))
				return false;

			// Parse number
			// TODO: Checks
			tz.next().toInt(map.level_num);
		}

		// Sky1
		else if (tz.check("sky1"))
		{
			if (!checkEqualsToken(tz, "ZMapInfo"))
				return false;

			map.sky1 = tz.next().text;

			// Scroll speed
			// TODO: Checks
			if (tz.advIfNext(","))
				tz.next().toFloat(map.sky1_scroll_speed);
		}

		// Sky2
		else if (tz.check("sky2"))
		{
			if (!checkEqualsToken(tz, "ZMapInfo"))
				return false;

			map.sky2 = tz.next().text;

			// Scroll speed
			// TODO: Checks
			if (tz.advIfNext(","))
				tz.next().toFloat(map.sky2_scroll_speed);
		}

		// Skybox
		else if (tz.check("skybox"))
		{
			if (!checkEqualsToken(tz, "ZMapInfo"))
				return false;

			map.sky1 = tz.next().text;
		}

		// DoubleSky
		else if (tz.check("doublesky"))
			map.sky_double = true;

		// ForceNoSkyStretch
		else if (tz.check("forcenoskystretch"))
			map.sky_force_no_stretch = true;

		// SkyStretch
		else if (tz.check("skystretch"))
			map.sky_stretch = true;

		// Fade
		else if (tz.check("fade"))
		{
			if (!checkEqualsToken(tz, "ZMapInfo"))
				return false;

			if (!strToCol(tz.next().text, map.fade))
				return false;
		}

		// OutsideFog
		else if (tz.check("outsidefog"))
		{
			if (!checkEqualsToken(tz, "ZMapInfo"))
				return false;

			if (!strToCol(tz.next().text, map.fade_outside))
				return false;
		}

		// EvenLighting
		else if (tz.check("evenlighting"))
		{
			map.lighting_wallshade_h = 0;
			map.lighting_wallshade_v = 0;
		}

		// SmoothLighting
		else if (tz.check("smoothlighting"))
			map.lighting_smooth = true;

		// VertWallShade
		else if (tz.check("vertwallshade"))
		{
			if (!checkEqualsToken(tz, "ZMapInfo"))
				return false;

			// TODO: Checks
			tz.next().toInt(map.lighting_wallshade_v);
		}

		// HorzWallShade
		else if (tz.check("horzwallshade"))
		{
			if (!checkEqualsToken(tz, "ZMapInfo"))
				return false;

			// TODO: Checks
			tz.next().toInt(map.lighting_wallshade_h);
		}

		// ForceFakeContrast
		else if (tz.check("forcefakecontrast"))
			map.force_fake_contrast = true;

		tz.adv();
	}
예제 #3
0
/* MapSpecials::processACSScripts
 * Process 'OPEN' ACS scripts for various specials - sector colours,
 * slopes, etc.
 *******************************************************************/
void MapSpecials::processACSScripts(ArchiveEntry* entry)
{
	sector_colours.clear();
	sector_fadecolours.clear();

	if (!entry || entry->getSize() == 0)
		return;

	Tokenizer tz;
	tz.setSpecialCharacters(";,:|={}/()");
	tz.openMem(entry->getMCData(), "ACS Scripts");

	while (!tz.atEnd())
	{
		if (tz.checkNC("script"))
		{
			LOG_MESSAGE(3, "script found");

			tz.adv(2);	// Skip script #

			// Check for open script
			if (tz.checkNC("OPEN"))
			{
				LOG_MESSAGE(3, "script is OPEN");

				// Skip to opening brace
				while (!tz.check("{"))
					tz.adv();

				// Parse script
				while (!tz.checkOrEnd("}"))
				{
					// --- Sector_SetColor ---
					if (tz.checkNC("Sector_SetColor"))
					{
						// Get parameters
						auto parameters = tz.getTokensUntil(")");

						// Parse parameters
						long val;
						int tag = -1;
						int r = -1;
						int g = -1;
						int b = -1;
						for (unsigned a = 0; a < parameters.size(); a++)
						{
							if (parameters[a].text.ToLong(&val))
							{
								if (tag < 0)
									tag = val;
								else if (r < 0)
									r = val;
								else if (g < 0)
									g = val;
								else if (b < 0)
									b = val;
							}
						}

						// Check everything is set
						if (b < 0)
						{
							LOG_MESSAGE(2, "Invalid Sector_SetColor parameters");
						}
						else
						{
							sector_colour_t sc;
							sc.tag = tag;
							sc.colour.set(r, g, b, 255);
							LOG_MESSAGE(3, "Sector tag %d, colour %d,%d,%d", tag, r, g, b);
							sector_colours.push_back(sc);
						}
					}
					// --- Sector_SetFade ---
					else if (tz.checkNC("Sector_SetFade"))
					{
						// Get parameters
						auto parameters = tz.getTokensUntil(")");

						// Parse parameters
						long val;
						int tag = -1;
						int r = -1;
						int g = -1;
						int b = -1;
						for (unsigned a = 0; a < parameters.size(); a++)
						{
							if (parameters[a].text.ToLong(&val))
							{
								if (tag < 0)
									tag = val;
								else if (r < 0)
									r = val;
								else if (g < 0)
									g = val;
								else if (b < 0)
									b = val;
							}
						}

						// Check everything is set
						if (b < 0)
						{
							LOG_MESSAGE(2, "Invalid Sector_SetFade parameters");
						}
						else
						{
							sector_colour_t sc;
							sc.tag = tag;
							sc.colour.set(r, g, b, 0);
							LOG_MESSAGE(3, "Sector tag %d, fade colour %d,%d,%d", tag, r, g, b);
							sector_fadecolours.push_back(sc);
						}
					}

					tz.adv();
				}
			}
		}

		tz.adv();
	}
}
예제 #4
0
파일: ZScript.cpp 프로젝트: Talon1024/SLADE
// -----------------------------------------------------------------------------
// Parses a ZScript 'statement'. This isn't technically correct but suits our
// purposes well enough
//
// tokens
// {
//     block[0].tokens
//     {
//         block[0].block[0].tokens;
//         ...
//     }
//
//     block[1].tokens;
//     ...
// }
// -----------------------------------------------------------------------------
bool ParsedStatement::parse(Tokenizer& tz)
{
	// Check for unexpected token
	if (tz.check('}'))
	{
		tz.adv();
		return false;
	}

	line = tz.lineNo();

	// Tokens
	bool in_initializer = false;
	while (true)
	{
		// End of statement (;)
		if (tz.advIf(';'))
			return true;

		// DB comment
		if (tz.current().text.StartsWith(db_comment))
		{
			tokens.push_back(tz.current().text);
			tokens.push_back(tz.getLine());
			return true;
		}

		if (tz.check('}'))
		{
			// End of array initializer
			if (in_initializer)
			{
				in_initializer = false;
				tokens.emplace_back("}");
				tz.adv();
				continue;
			}

			// End of statement
			return true;
		}

		if (tz.atEnd())
		{
			Log::debug(S_FMT("Failed parsing zscript statement/block beginning line %u", line));
			return false;
		}

		// Beginning of block
		if (tz.advIf('{'))
			break;

		// Array initializer: ... = { ... }
		if (tz.current().text.Cmp("=") == 0 && tz.peek() == '{')
		{
			tokens.emplace_back("=");
			tokens.emplace_back("{");
			tz.adv(2);
			in_initializer = true;
			continue;
		}

		tokens.push_back(tz.current().text);
		tz.adv();
	}

	// Block
	while (true)
	{
		if (tz.advIf('}'))
			return true;

		if (tz.atEnd())
		{
			Log::debug(S_FMT("Failed parsing zscript statement/block beginning line %u", line));
			return false;
		}

		block.push_back({});
		block.back().entry = entry;
		if (!block.back().parse(tz) || block.back().tokens.empty())
			block.pop_back();
	}
}