Upload
lucy-marshall
View
215
Download
1
Embed Size (px)
Citation preview
Programming ParrotProgramming Parrot
Important safety tips!Important safety tips!
• Parrot has no safety net• You can crash pretty easily• Parrot’s not entirely bug-free• All the ops are documented• perldoc ops/file.ops• (Knowing the right file can be
interesting)
PASM & PIRPASM & PIR
• PASM - Parrot assembly• PIR - Parrot Intermediate
Representation• PASM is simple• PIR is convenient• Mix and match across files
Standard extensionsStandard extensions
• .pasm - Parrot assembly• .imc - Parrot intermediate
representation• .pbc - Parrot bytecode
Invoking ParrotInvoking Parrot
• parrot foo.pbc• parrot -o foo.pbc foo.imc• parrot -o foo.pbc foo.pasm• parrot foo.pasm• parrot foo.imc• parrot -o foo.pasm foo.imc
Extension autodetectExtension autodetect
• Source automatically compiled and run
• Input type based on extension• Output type based on extension• No automatic decompilation,
though
Behold, the opcpdeBehold, the opcpde
• opname [dest,] [source[, source…]]
• add I2, I3, I4• print “some thing\n”• PIR shortcut:
dest = op source1, source2
same asop dest, source1, source2
ConstantsConstants
• Signed integer constants• Floating point constants• Single or double quoted string
constants• Standard string backslash escapes
apply
Named constantsNamed constants
.const type name = value
.const int five = 5
.const str error = “Don’t do that!”• Constants are scoped to the
compilation unit
Include filesInclude files
.include “filename”• Includes the file as if it were right
there• Nothing fancy• No path searching right now
Subroutine propertiesSubroutine properties
• Go after sub name, comma-separated• method, prototyped, @LOAD, @MAIN• method - self filled in with calling object• prototyped - takes or returns non-PMCs• @MAIN - main sub for bytecode file• @LOAD - sub to execute on bytecode
load
Basic MathBasic Math
• add, sub, mul, div• mod and cmod• inc and dec• Transcendental math• Docs: ops/math.ops
PIR shortcutsPIR shortcuts
• Infix math works• Normal notation works• I3 = I5 + I6• $P6 = $P6 - 5• result = source * 4• C shortcuts work• $P6 += 4
Safety tipSafety tip
• PMC destination generally must exist
• Op docs sayabs(in PMC, in PMC) must existfind_global(out PMC, in STR, in STR)
returned
Creating PMCsCreating PMCs
• new dest, type• dest = new type• Type can be a predefined constant
line = new Integerline = foo + 12
• Undef is a good type for temps (it changes type on first assignment)
Basic PMC typesBasic PMC types
• Boolean• Integer• String• Float• Null• Undef
• Env• FixedtypeArray• ResizeabletypeArr
ay
Finding PMC typesFinding PMC types
• Basic types have predefined constants
• User types can be found with find_type$I4 = find_type ‘String’
• Type of an existing PMC with typeof$I5 = typeof $P5$S5 = typeof $P5
Named tempsNamed temps
.local type name• sub-local• Automatically spilled, just like
virtual registers• PMC locals must still be new’d• Virtual registers don’t
automagically have a valid destination
Basic string opsBasic string ops
• Concatenation:$S4 = concat $S5, $S6
• Repetition$S5 = repeat “ “, 10
• Finding substringoffset = index source, substring[, start]
• String lengthstrlen = length $S103
String length trickyString length tricky
• Bytes, code points, and characters• bytelength, codepointlength,
graphemelength, respectively• length is shortcut for
graphemelength• Part of encoding upgrade in
process
Calling SubroutinesCalling Subroutines
foo()foo(1, 2, $S4, $P5)result = foo(1, 2, 3)(result1, result2) = foo(1, 2, 3)
• Can call a PMC representing a sub, or a sub in the current namespace
• No typechecking!
Returning valuesReturning values
.pcc_begin_return.result xxx
.pcc_end_return• No type checking. Get it right or
find bizarre bugs later
Moving aroundMoving around
• Labels end with a colonexit_spot:
• Labels are sub local• branch goes to a label
branch exit_spot• jump goes to a label too• branch is relative, jump absolute• Use branch
Branch basicsBranch basics
• Branches are relative• 2G offset plus or minus• We’ve not found this to be a
limitation in practice
Tiny subsTiny subs
• bsr branches to a label too• Pushes return address on stack• ret will return from a bsr• Much lighter-weight than a sub call• No calling conventions• Must stay within a sub
Conditional Branch: ifConditional Branch: if
if thing, label• Tests thing for truth, branches if
true• Numbers: 0 is false• Strings: Empty string or string “0”• PMCs: We ask them
Comparison branchesComparison branches
• eq, ne, lt, gt, ge, le• Same type, or low type and PMC• Each has an _str and _num variant
to force string or numeric comparisons
Existence branchesExistence branches
isnull thing, dest• Used for strings and PMCs• Branches if the register has a NULL
pointer or a Null PMC in it
PIR shortcutsPIR shortcuts
if thing1 op thing2 goto label• Op is <, >, <=, >=, !=, ==• No then in there
Assignment and value setting
Assignment and value setting
• Int and Floats are value types• PMCs and Strings are reference
types• Simple assignment with set
set I5, I6set S4, S6
• Copies contents of register• Aliases PMCs and Strings
Assignment and value setting
Assignment and value setting
• Assign copies the dataassign $P4, $P5
• Calls destination’s set function• Works for strings and PMCs
Cross-type assignmentCross-type assignment
• Source and destination different basic types
• Performs automatic conversion• PIR = does assignment
$S5 = $I5$N5 = $P5
Input and outputInput and output
• Basic filehandle-based IO system• Async & event driven under the
hood• (When we get that finished)
OutputOutput
• Simple output with print• Prints any type, as well as
constants• Integers and floats get stringified• PMCs get their __get_string
methods called• To stdout by default• Or provide a filehandle
OutputOutput
print “Hello, world\n”printerr “Hello, error world\n”print some_filehandle, “Hello, filehandle\
n”
InputInput
• Block-oriented reads$S1 = read 10
$S2 = read $P4, 10
• Line-oriented reads$S2 = readline $P4
• Line reads stop at newline or 64k, whichever comes first
Standard filehandlesStandard filehandles
• getstdin, getstdout, getstderr fetch filehandles$P5 = getstdin$S5 = readline $P4
Opening filesOpening files
• Open with open• $P5 = open “filename”, file_mode
• Returns an undef on error• File modes are perl-like:
• >, <, >>, +<, +>• fopen r, w, a, r+, and w+ modes
• Only files right now
File infoFile info
• stat and fstat ops return stat info on files
• stat uses filenames, fstat file numbers$I5 = stat ‘foo.txt’, STAT_FILESIZE$I6 = fstat 2, STAT_FILESIZE
• Constants defined in runtime/parrot/include/stat.pasm
• Both portable and non-portable data there
Global variablesGlobal variables
• Parrot has a hierarchic, unified global variable store
• Each sub has a default namespace• Set with .namespace directive
.namespace [‘Foo’; ‘Bar’]
• Global store only holds PMCs
Fetching globalsFetching globals
• Fetch with find_global$P6 = find_global ‘globalname’$P6 = find_global [‘foo’; ‘bar’], ‘globalname’
• Fetches a pointer!• Changes to PMC will be changed in
global store• Throws exception on failure
Storing GlobalsStoring Globals
• Store with store_globalstore_global ‘name’, $P5store_global [‘foo’; ‘bar’], ‘varname’,
$P5
• Overwrites whatever was there• Not an assignment
ClassesClasses
• Simple slot-based object system• Actively instantiated• Multiple inheritance• No metaclasses (yet)
Creating a classCreating a class
• New base class uses newclassclass_pmc = newclass ‘classname’
• Subclass with subclassnew_class = subclass ‘parent’, ‘classname’new_class = subclass class_pmc, ‘classname’anon_class = subclass ‘classname’anon_class = subclass class_pmc
Modifying a classModifying a class
• Add a parent class with addparentaddparent my_class, new_parent
• Remove a parent class with removeparentremoveparent my_class, gone_parent
• Add an attribute with addattributeaddattribute class_pmc, ‘attrib_name’
Safety tipSafety tip
• Not a good idea to modify classes with instantiated objects
• Though it will work• (Just doesn’t work too well right
now)
Class tipsClass tips
• Easiest to put classes into their own file
• Handle all the class setup in the file’s @INIT-tagged function
• One class per file, with all methods in it, works pretty well
Attribute accessAttribute access
• classoffset gets the offset of the first attribute of a class in an object$I5 = classoffset object, ‘Foo’
• getattribute fetches an attribute from an object$P5 = getattribute object, $I5
• You do the math• No protection at this level
MethodsMethods
• Very simple• Optionally add method to .sub
definition• Just names in the class namespace• Classes can override this if they want• Do a leftmost depth-first search for
methods• All __init methods always called when
instantiating
Method callsMethod calls
• Like sub calls, only with an object(foo, bar) = $P6.methname(1,2, ‘3’)
• Nice and simple• Works for all objects (and non-
objects, if they want)
Vtable methodsVtable methods
• Object can override all the PMC vtable functions
• Search up the hierarchy until one is found
• 134 basic vtable methods, so we’re not listing them all here
• Look in vtable.tbl for the list and parameters
• Prepend a __ for the parrot method name
Common vtable methodsCommon vtable methods
__get_integer__get_number__get_string__get_bool__get_pmc
__set_integer_native__set_number_native__set_string_native__assign_string_native__set_bool__set_pmc
MMDMMD
• Only in for some opcode functions right now
• Dispatch based on left and right types
• Basic fallbacks provided• All basic math, comparison, and
bitwise operations covered
MMDMMD
• Use mmdvtregister to add a new function to a tablemmdvtregister MMD_ADD, $I4, $I5, subPMC
• Second and third parameter are type numbers
• Function numbers in runtime/parrot/include/mmd.pasm
• Tables can be dynamically extended
Loading filesLoading files
load_bytecode “file”• Uses same rules as command-line
invocation• PIR and PASM files can be loaded• @LOAD subs of loaded files
executed• Throws exception on error
Debugging supportDebugging support
• -t switch traces all ops• -p switch profiles code• -G or --no-gc disables garbage
collector• --gc-debug enables stressful
collector
Loading external librariesLoading external libraries
• Open the library with loadlib$P4 = loadlib ‘libcurses’
• Create wrappers with dlfunc$P5 = dlfunc $P4, ‘resizeterm’, ‘iii’
• Stick the results somwherestore_global [‘ncurses’], ‘resizeterm’,
$P5
Parameter descriptionsParameter descriptions
I register • c - char• s - short• i - int• l - longN register• f - float• d - doubleS registers stuff• t - character stringP registers • p - data pointer from PMC • P - pointer to a PMC-register• O - pointer to object
Others• 2 - pointer to short• 3 - pointer to int• 4 - pointer to longspecial stuff• 0 - insert a NULL
(pointer)• I - Parrot_Interp• L - Long array• T - Array of string
pointers (Converted to cstrings)