Games-Axmud
view release on metacpan or search on metacpan
lib/Language/Axbasic.pm view on Meta::CPAN
# the specified LA::RawScript object
# (LA::RawScript contains a script includes whitespace, empty lines, comments and possibly
# line numbers; LA::Script contains a script with all that stuff removed)
#
# Once created, the script stored in this object can be accessed in two modes:
# - Call ->parse to parse the script, looking for errors, but don't actually execute it
# - Call ->implement to parse the script, line-by-line, and then execute it
# If the Axbasic script pauses (usually when the script is being executed as an Axmud task),
# call ->parse or ->implement again to resume execution
#
# Expected arguments
# $session - The parent GA::Session
#
# Optional arguments
# $rawScriptObj - Blessed reference of the LA::RawScript from which to download the
# Axbasic script. If not specified, no script is downloaded (this
# is useful for accessing default values stored in this object's IVs)
#
# Return values
# 'undef' on improper arguments, or if the specified raw script can't be uploaded or if
# there's an error setting up intrinsic function objects
# Blessed reference to the newly-created object on success
my ($class, $session, $rawScriptObj, $check) = @_;
# Local variables
my (
@keywordList, @logicalOpList,
%keywordHash,
);
# Check for improper arguments
if (! defined $class || ! defined $session || defined $check) {
return $axmud::CLIENT->writeImproper($class . '->new', @_);
}
# Define the list of Axbasic keywords - used to set more than one IV
@keywordList = (
'access', 'addalias', 'addcongauge', 'addconstatus', 'addgauge', 'addhook', 'addmacro',
'addstatus', 'addtimer', 'addtrig', 'angle', 'array', 'beep', 'begin', 'break',
'bypass', 'call', 'case', 'client', 'cls', 'close', 'closewin', 'create', 'data',
'debug', 'def', 'degrees', 'delalias', 'delgauge', 'delhook', 'deliface', 'delmacro',
'delstatus', 'deltimer', 'deltrig', 'dim', 'dimensions', 'do', 'each', 'else',
'elseif', 'emptywin', 'end', 'erase', 'error', 'exit', 'flashwin', 'for', 'global',
'gosub', 'goto', 'help', 'if', 'in', 'input', 'let', 'local', 'login', 'loop', 'lower',
'multi', 'move', 'name', 'needtask', 'new', 'newold', 'next', 'nextiface', 'nolet',
'numeric', 'old', 'on', 'open', 'openentry', 'openwin', 'option', 'org', 'organization',
'outin', 'output', 'paintwin', 'pause', 'peek', 'peekequals', 'peekexists', 'peekfind',
'peekfirst', 'peekget', 'peekindex', 'peekkeys', 'peeklast', 'peekmatch', 'peeknumber',
'peekpairs', 'peekshow', 'peekvalues', 'perl', 'persist', 'play', 'poke', 'pokeadd',
'pokedec', 'pokedechash', 'pokedelete', 'pokedivide', 'pokeempty', 'pokefalse',
'pokeinc', 'pokeinchash', 'pokeint', 'pokeminus', 'pokemultiply', 'pokeplus', 'pokepop',
'pokepush', 'pokereplace', 'pokeset', 'pokeshift', 'poketrue', 'pokeundef',
'pokeunshift', 'pop', 'print', 'profile', 'pseudo', 'push', 'radians', 'randomize',
'read', 'redim', 'redirect', 'relay', 'rem', 'require', 'reset', 'restore', 'return',
'revpath', 'select', 'send', 'setalias', 'setgauge', 'sethook', 'setmacro', 'setstatus',
'settimer', 'settrig', 'shift', 'silent', 'size', 'skipiface', 'sleep', 'sort',
'sortcase', 'sortcaser', 'sortr', 'speak', 'speed', 'step', 'stop', 'string', 'sub',
'tab', 'text', 'titlewin', 'then', 'to', 'typo', 'unflashwin', 'unshift', 'until',
'upper', 'waitactive', 'waitalias', 'waitalive', 'waitarrive', 'waitdead', 'waitep',
'waitgp', 'waithook', 'waithp', 'waitmacro', 'waitmp', 'waitnextxp', 'waitnotactive',
'waitpassout', 'waitscript', 'waitsleep', 'waitsp', 'waittask', 'waittimer',
'waittotalxp', 'waittrig', 'waitxp', 'warning', 'while', 'winaddcongauge',
'winaddconstatus', 'winaddgauge', 'winaddstatus', 'windelgauge', 'windelstatus',
'winsetgauge', 'winsetstatus', 'write', 'writewin',
);
foreach my $keyword (@keywordList) {
$keywordHash{$keyword} = undef;
}
# Define the list of logical operators - used to set more than one IV
@logicalOpList = ('and', 'or', 'not');
# Setup
my $self = {
_objName => $class, # Name Axbasic objects after their class
_objClass => $class,
_parentFile => undef, # No parent file object
_parentWorld => undef, # No parent file object
_privFlag => TRUE, # All IVs are private
# Perl object components
# ----------------------
# The parent GA::Session
session => $session,
# Script IVs
# ----------
# The script name (matches the ->name of the LA::RawScript object from which the Axbasic
# script has been downloaded; set to 'undef' until then)
name => undef,
# The full file path from which the script is loaded, every time LA::RawScript->loadFile
# is called (set by this function, if a script is downloaded, but remains set to
# 'undef' otherwise)
filePath => undef,
# All the lines in the script, a hash in the form
# $lineHash{line_number} = blessed_reference_to_LA::Line object
# The first line number is $lineHash{1}
lineHash => {},
# How many lines in total (0 when the script is empty)
lineCount => 0,
# The current line number (matches a key in $self->lineHash)
currentLine => undef,
# The next line to execute (the line's ->procLineNum, not its blessed reference)
nextLine => undef,
# Blessed reference of the next statement to execute
nextStatement => undef,
# A hash to convert primitive line numbers into ->procLineNum values
# e.g. 10 PRINT "hello"
# 20 GOTO 10
# key = 10, value = 0 / key = 20, value = 1
primLineHash => {},
# Execution mode:
lib/Language/Axbasic.pm view on Meta::CPAN
'lower' => 'let',
'name' => 'open',
'needtask' => 'option',
'new' => 'open',
'newold' => 'open',
'nolet' => 'option',
'numeric' => 'sub',
'old' => 'open',
'org' => 'open',
'organization' => 'open',
'outin' => 'open',
'output' => 'open',
'persist' => 'option',
'pseudo' => 'option',
'radians' => 'option',
'redirect' => 'option',
'require' => 'option',
'silent' => 'option',
'size' => 'let',
'step' => 'for',
'string' => 'sub',
'tab' => 'print',
'text' => 'open',
'then' => 'for',
'to' => 'for',
'typo' => 'option',
'upper' => 'let',
},
# A hash of keywords that are either synonyms of other keywords (such as PAUSE and
# SLEEP), or whose code is so similar that their LA::Statement objects should be
# combined (such as ADDGAUGE and ADDCONGAUGE)
equivKeywordHash => {
'addcongauge' => 'addgauge',
'addconstatus' => 'addstatus',
'elseif' => 'else',
'sleep' => 'pause',
'winaddcongauge' => 'addgauge',
'winaddconstatus' => 'addstatus',
'winaddgauge' => 'addgauge',
'winaddstatus' => 'addstatus',
'windelgauge' => 'delgauge',
'windelstatus' => 'delstatus',
'winsetgauge' => 'setgauge',
'winsetstatus' => 'setstatus',
},
# A list of statements that interact directly with Axmud
clientKeywordList => [
'addalias', 'addcongauge', 'addconstatus', 'addgauge', 'addstatus', 'addhook',
'addmacro', 'addtimer', 'addtrig', 'array', 'beep', 'break', 'bypass', 'client',
'closewin', 'debug', 'delalias', 'delgauge', 'deliface', 'delhook', 'delmacro',
'delstatus', 'deltimer', 'deltrig', 'emptywin', 'error', 'flashwin', 'login',
'move', 'multi', 'nextiface', 'openentry', 'openwin', 'paintwin', 'pause', 'peek',
'peekequals', 'peekexists', 'peekfind', 'peekfirst', 'peekget', 'peekindex',
'peekkeys', 'peeklast', 'peekmatch', 'peeknumber', 'peekpairs', 'peekshow',
'peekvalues', 'perl', 'play', 'poke', 'pokeadd', 'pokedec', 'pokedechash',
'pokedelete', 'pokedivide', 'pokeempty', 'pokefalse', 'pokeinc', 'pokeinchash',
'pokeint', 'pokeminus', 'pokemultiply', 'pokeplus', 'pokepop', 'pokepush',
'pokereplace', 'pokeset', 'pokeshift', 'poketrue', 'pokeundef', 'pokeunshift',
'profile', 'relay', 'revpath', 'send', 'setalias', 'setgauge', 'sethook',
'setmacro', 'setstatus', 'settimer', 'settrig', 'skipiface', 'sleep', 'speak',
'speed', 'titlewin', 'unflashwin', 'waitactive', 'waitalias', 'waitalive',
'waitarrive', 'waitdead', 'waitep', 'waitgp', 'waithook', 'waithp', 'waitmacro',
'waitmp', 'waitnextxp', 'waitpassout', 'waitscript', 'waitsleep', 'waitsp',
'waittask', 'waittimer', 'waittotalxp', 'waittrig', 'waitxp', 'warning',
'winaddcongauge', 'winaddconstatus', 'winaddgauge', 'winaddstatus', 'windelgauge',
'windelstatus', 'winsetgauge', 'winsetstatus', 'write', 'writewin',
],
# A list of keywords that are ignored when the Axbasic script isn't being run from
# within a task
taskKeywordList => [
'addcongauge', 'addgauge', 'addconstatus', 'addstatus', 'break', 'closewin',
'delgauge', 'emptywin', 'flashwin', 'openentry', 'openwin', 'paintwin', 'pause',
'setalias', 'setgauge', 'sethook', 'setmacro', 'settimer', 'settrig', 'sleep',
'titlewin', 'unflashwin', 'waitactive', 'waitalias', 'waitalive', 'waitarrive',
'waitdead', 'waitep', 'waitgp', 'waithook', 'waithp', 'waitmacro', 'waitmp',
'waitnextxp', 'waitnotactive', 'waitpassout', 'waitscript', 'waitsleep', 'waitsp',
'waittask', 'waittimer', 'waittotalxp', 'waittrig', 'waitxp', 'winaddcongauge',
'winaddconstatus', 'winaddgauge', 'winaddstatus', 'windelgauge', 'windelstatus',
'winsetgauge', 'winsetstatus', 'writewin',
],
# A list of logical operators ('and', 'or', 'not')
logicalOpList => \@logicalOpList,
# A list of regular expression with which to split a line of Axbasic into a series of
# tokens, in the format
# $regexHash{token_category} = regex_to_identify_it
regexHash => {
'short_comment' => '(?i)!($|.*)',
'comment' => '(?i)REM($|\s.*)',
'keyword' => "(?i)(" . join("|", @keywordList) . ")\\b",
'identifier' => '(?i)[A-Z][A-Z0-9_]*\\$?',
'logical_operator' => "(?i)(" . join("|", @logicalOpList) . ")\\b",
'string_constant' => '".*?"',
'numeric_constant' => '(\\d*\\.)?\\d+',
'left_paren' => '\\(',
'right_paren' => '\\)',
'file_channel' => '\#[0-9]+\s*\:?',
'separator' => '[,;]' ,
'arithmetic_operator' => '[-+&]',
'multiplicative_operator'
=> '[*/\^]',
'relational_operator' => '<[=>]?|>=?|=',
'assignment_operator' => '=',
'statement_end' => ':',
},
# The list of token categories, in a standard order
categoryList => [
'short_comment',
'comment',
'keyword',
'identifier',
'logical_operator',
'string_constant',
'numeric_constant',
'left_paren',
'right_paren',
'file_channel',
'separator',
'arithmetic_operator',
'multiplicative_operator',
'relational_operator',
'assignment_operator',
'statement_end',
],
# The script's status:
# 'waiting' - parsing (or implementation) not yet started
# 'parsing' - being parsed (or implemented)
# 'paused' - being parsed (or implemented), but paused (normally when the Axbasic
# script is being run as an Axmud task)
# 'wait_input' - being implemented (when the Axbasic script is being run as an Axmud
# task), but waiting for INPUT
# 'finished' - parsed (or implemented) and finished
lib/Language/Axbasic.pm view on Meta::CPAN
'max' => 'NN',
'min' => 'NN',
'mod' => 'NN',
'ncpos' => 'SS;N',
'ncposr' => 'SS;N',
'pi' => '',
'pos' => 'SS;N',
'posr' => 'SS;N',
'rad' => 'N',
'remainder' => 'NN',
'rnd' => 'N',
'round' => 'N;N',
'sec' => 'N',
'sgn' => 'N',
'sin' => 'N',
'sinh' => 'N',
'sqr' => 'N',
'tan' => 'N',
'tanh' => 'N',
'testpat' => 'S',
'time' => '',
'trunc' => 'N;N',
'val' => 'S',
'version' => '',
# Pure BASIC functions (returning a string value)
'chr$' => 'N',
'date$' => '',
'ip$' => '',
'lcase$' => 'S',
'left$' => 'SN',
'ltrim$' => 'S',
'mid$' => 'SN;N',
'repeat$' => 'SN',
'right$' => 'SN',
'rtrim$' => 'S',
'str$' => 'N',
'testpat$' => 'S',
'time$', => '',
'trim$' => 'S',
'ucase$' => 'S',
# Axmud-dependent functions (returning a numeric value)
'addexit' => 'NS;S',
'addfirstroom' => '',
'addlabel' => 'SNNN',
'addregion' => 'S',
'addroom' => 'NNN',
'addtempregion' => ';S',
'addtwinexit' => 'N',
'closemap' => '',
'connectexit' => 'NN',
'counttask' => 'S',
'delexit' => 'N',
'delregion' => 'S',
'delroom' => 'N',
'deltempregions' => '',
'disconnectexit' => 'N',
'getexitdest' => 'N',
'getexitnum' => 'N',
'getexittwin' => 'N',
'getlostroom' => '',
'getobjectalive' => 'N',
'getobjectcount' => 'N',
'getregionnum' => '',
'getroomexits' => '',
'getroomnum' => '',
'getroomobjects' => ';S',
'ifacecount' => '',
'ifacedefined' => 'N',
'ifacepos' => '',
'ifacenum' => '',
'ifacestrings' => '',
'ifacetime' => '',
'isexit' => 'N',
'isfinished' => 'S',
'ishiddenexit' => 'N',
'isregion' => 'S',
'isroom' => 'N',
'isscript' => '',
'ismap' => '',
'istask' => '',
'istempregion' => 'S',
'iswin' => '',
'openmap' => '',
'sethiddenexit' => 'N',
'setlight' => 'S',
'setmapmode' => 'S',
'setornament' => 'N;S',
'setrandomexit' => 'N;S',
'setregion' => 'S',
'setregionnum' => 'N',
'setroomnum' => ';N',
'setroomtagged' => ';S',
'timestamp' => '',
# Axmud-dependent functions (returning a string value)
'abbrevdir$' => 'S',
'clientdate$' => '',
'clientname$' => '',
'clientversion$' => '',
'findtask$' => 'S',
'getexit$' => 'N',
'getexitdrawn$' => 'N',
'getexitstatus$' => 'N',
'getexittype$' => 'N',
'getlight$' => '',
'getmapmode$' => '',
'getobject$' => 'N',
'getobjectnoun$' => 'N',
'getobjecttype$' => 'N',
'getornament$' => 'N',
'getrandomexit$' => 'N',
'getregion$' => '',
'getroomdescrip$' => ';S',
'getroomguild$' => '',
'getroomsource$' => '',
'getroomtag$' => '',
'getroomtitle$' => '',
'iface$' => '',
'ifacedata$' => '',
'ifacename$' => '',
'ifacepop$' => '',
'ifaceselect$' => 'N',
( run in 0.968 second using v1.01-cache-2.11-cpan-39bf76dae61 )