User:N0one/Sandbox/VScriptLexer

From Valve Developer Community
Jump to navigation Jump to search

An example of how <syntaxhighlight lang="vscript"> would look once implemented:

// Test File

// ////

// Single line comment

/*
multi comment
*/

// String test

StringTest = "This is a string with an escaped quote: \" and a newline: \n and a backslash: \\ and a tab: \t and a hex escape: \x41"
StringSingle = 'A'

// Number test

pi = 3.14159
number = 128
huge_number = 1.23e+10
huge_number_negative = -1.23e-10
SomeHex = 0x1A2B3C


// Control flow test

if (pi > 3) {
print("Pi is greater than 3");
} else {
print("Pi is not greater than 3");
}

// constant test

const PI = 3.14159
const HELLO_WORLD = "Hello, World!"

// function test

function add(a, b) {
return a + b;
}

function IsEven(n) {
if (n % 2 == 0) {
return true;
} else {
return false;
}
}

// Class test

class MyClass {
//contructor
constructor( plr, target, team )
{
this.plr = plr
this.target = target
this.team = team
}

//member function
function Describe()
{
printl( "Player " + this.plr + " " + this.target + ".." + this.team )
}

//property
plr = null;
target = null;
team = null;
}

class Alien extends Entity
{
}

// Anonymous function test

@(params) printl("This is an anonymous function");

// Global test

::GlobalVar <- 256

MyVar <- "abc"
MyVar.Something <- "abc"
MyVar.Lorem.Ipsum <- "abc"

// Operator test

if (IsEven(10) && !IsEven(11) || (5 < 10)) {
print("Operators work!");
}

// Misc

clone

this
self
activator
caller

null
true
false

delete ::GlobalVar
typeof

NULL

foreach (MAX_ITEMS in someList) {
print(MAX_ITEMS);
}

player.AddHudHideFlags(
Constants.FHideHUD.HIDEHUD_CROSSHAIR |
Constants.FHideHUD.HIDEHUD_HEALTH |
Constants.FHideHUD.HIDEHUD_WEAPONSELECTION
) // hides hud elements

player.RemoveHudHideFlags(player,
Constants.FHideHUD.HIDEHUD_CROSSHAIR |
Constants.FHideHUD.HIDEHUD_HEALTH |
Constants.FHideHUD.HIDEHUD_WEAPONSELECTION
) // makes hud elements visible again


// Source SDK 2013 examples:

// Implementation

local function dummy_ent() {
// logic_relay does not take up an edict
local relay = Entities.CreateByClassname("logic_relay")
NetProps.SetPropBool(relay, "m_bForcePurgeFixedupStrings", true)
relay.ValidateScriptScope()
return relay
}

function RunWithDelay(func, delay = 0.0)
{
local dummy = dummy_ent()
dummy.GetScriptScope()["Run"] <- function[this]()
{
dummy.Kill()
func()
}

EntFireByHandle(dummy, "CallScriptFunction", "Run", delay, null, null)
return dummy
}

function CreateTimer(on_timer_func, first_delay = 0.0)
{
local dummy = dummy_ent()
dummy.GetScriptScope()["Run"] <- function[this]()
{
try
{
local delay = on_timer_func()

if (delay == null)
{
dummy.Kill()
return
}

// Delays which are less or equal to 0 will be executed in the current tick which leads to an infinite loop
if (delay <= 0.0)
delay = 0.01

EntFireByHandle(dummy, "CallScriptFunction", "Run", delay, null, null)
}
catch (err)
{
dummy.Kill()
throw err
}
}

EntFireByHandle(dummy, "CallScriptFunction", "Run", first_delay, null, null)
return dummy
}

function KillTimer(timer)
{
if (timer.IsValid())
timer.Kill()
}

function FireTimer(timer)
{
if (timer.IsValid())
{
timer.GetScriptScope()["Run"]()
KillTimer(timer)
}
}

// Example
scope_var <- 1

local fired = false
local timer = CreateTimer(function()
{
if (!fired)
{
printl("This is the first fire")
fired = true
// Repeat after 1 second
return 1.0
}
else
{
printl("This is not a first fire")
// repeat after 2 seconds
return 2.0
}
// First fire will be after 1 second
}, 1.0)

// Fire and kill the timer after 7 seconds
RunWithDelay(@() printl("Firing and killing a timer..."), 7.0)
RunWithDelay(@() FireTimer(timer), 7.0)
RunWithDelay(@() printl("Scope var is " + scope_var), 8.0)

// Implementation

function MultipleThinks()
{
local time = Time()
foreach (name, func in ThinkTable)
{
if (ThinkDelays[name] > time)
continue

local delay = func()
if (delay == null || delay < 0.0)
delay = 0.0

ThinkDelays[name] = time + delay
}

return -1
}

function AddThinkTable(entity)
{
entity.ValidateScriptScope()
local scope = entity.GetScriptScope()

scope.ThinkTable <- {}
scope.ThinkDelays <- {}
scope.MultipleThinks <- MultipleThinks
AddThinkToEnt(entity, "MultipleThinks")

return scope
}

function AddThink(entity, name, func)
{
local scope = entity.GetScriptScope()
scope.ThinkTable[name] <- func//.bindenv(scope) seemingly has no impact
scope.ThinkDelays[name] <- 0.0
}

function RemoveThink(entity, name)
{
local scope = entity.GetScriptScope()
delete scope.ThinkDelays[name]
delete scope.ThinkTable[name]
}


// Example

local player = GetListenServerHost()
AddThinkTable(player)

function FirstThink() {
printl("Think1")
return 1.0
}
AddThink(player, "FirstThink", FirstThink)

AddThink(player, "SecondThink", function()
{
printl("Think2")
return 2.0
})