notkyon / tenshi Goto Github PK
View Code? Open in Web Editor NEWBasic language compiler
License: Other
Basic language compiler
License: Other
Tenshi's "break/continue" feature (exit loop
and repeat loop
respectively) needs a codegen implementation.
Suggestion: A simple stack in MCodeGen that holds a pair of llvm::BasicBlock
pointers at each level (one for breaking and one for continuing) would be an easy approach for implementation. Each "loop node" in the AST would then just have to make sure that it appropriately allocates these blocks before their inner loop gets evaluated, and to push/pop during its own codegen cycle.
When the compiler initializes its codegen component, MCodeGen
, that component initializes LLVM with a mostly hard-coded TargetMachine
which targets x86-64 with default code model, optimization, and relocation policies.
Rather than having these settings hard-coded, they should be derived from user configurations (command-line, project file) with reasonable defaults for anything not specifically set, depending on the mode (e.g., debug or release.)
Aside: Including explicit support for WebAssembly tools (like automatic s2bin invocation) would be a nice-to-have.
The current implementation of user-defined-types (UDTs) in Tenshi is rather loose, and does not closely adhere to C struct semantics. This will allow for easier bridging with C/C++ code.
User defined types (UDTs) do not currently implement full support for constructors (init), destructors (fini), or copy/move operations.
Automatic (sane) generation of these is required, as well as support for user-supplied constructors/destructors for special cases. There is currently no specific design for that in the language.
Tenshi has several built-in types which need a proper codegen implementation.
Vector2
Vector3
Vector4
Matrix2
Matrix3
Matrix4
Matrix23
Matrix24
Matrix32
Matrix34
Matrix42
Matrix43
Quaternion
These are essentially just various fixed-length arrays with different arithmetic semantics. The vector types, in particular, have support for "swizzling," just as popular shader languages do. e.g., myvec.xyz =othervec.yyy
.
Parameter passing conventions and various built-in operations need an implementation for these built-in types.
Aside: SIMD vectors are also planned, with names like float32x4
. Those are entirely different from these built-in types, and are not part of this issue.
gosub
and goback
are like the Dark Basic commands gosub
and return
, respectively. They can be invoked from within a function (including both the implicit function and explicit functions) to implement a sort of subroutine.
They were not implemented right away as there was no direct analogue to these concepts in LLVM. A separate "return stack" might need to be maintained in functions which utilize these commands.
However, these commands are generally considered bad practice even within Basic-centric communities. Perhaps they should be removed instead of implemented.
In any case, they are in a sort of limbo between existing and not existing and have been for a while.
Attributes, as defined in Code/Tenshi/TechDocs/Plugins.txt, requires an implementation.
Relevant excerpt:
Likewise the function called by "TURN OBJECT 1 LEFT 45.0 DEGREES" could be declared like so:
"TURN OBJECT%L:(LEFT)@[degrees,radians]F%turn_object_left_impl"
Attributes are passed as an integer. An integer value of 0 is given if no attribute is passed.
When specifying attributes in the type patterns list, you can also specify which attributes are acceptable (rather than "any valid string"). For example, taken from "select_w" (from RlDev) the following attributes might exist for a menu selection system:
hide Option is not displayed at all blank No option is given here, instead just a blank line colour(idx) Set the color of the option to the palette color `idx` title(idx) Disable the option, but keep it displayed; also allows a color cursor(idx) Display an icon next to the option (`idx` being the icon index)
As can be inferred from the above, there are times when some attributes may have parameters, while others might not. Parameters to attributes can be provided when valid attributes are listed.
An example of the "select_w" command's declaration:
select_w[%L@[hide,blank,colour(L),title(L=0),cursor(L)]S+%select_w_impl"
The declaration for select_w in C would then look something like this:
/* these are the possible attributes */ enum select_parm_attrib { /* this attribute is passed if no attribute is specified */ kSelectAttrib_None = 0, /* 'hide' */ kSelectAttrib_Hide, /* 'blank' */ kSelectAttrib_Blank, /* colour(colour_index) */ kSelectAttrib_Colour, /* title(colour_index=0) */ kSelectAttrib_Title, /* cursor(icon_index) */ kSelectAttrib_Cursor }; /* structured because of the "+" */ struct select_parm { /* "attrib" because of the "@" */ enum select_parm_attrib attrib; /* "attrib_index" because some attribs take an "L" parameter */ int attrib_index; /* "value" because of the "S" */ const char * value; }; /* returns "int" because of "[%L" (the '[' right before '%' means "returns," * and the next type sequence after that indicates the return type */ int select_w_impl( size_t num_parms, const select_parm *parms );Any code from the language itself is guaranteed to be valid as it is a compiler semantic error to attempt to pass an invalid attribute, and the compiler is to not call the function if it could not allocate the parameters needed (e.g., on the stack or on the heap).
Suppose there's also a "fade" attribute which takes a float value. The command declaration would then look like this:
select_w[%L@[hide,blank,colour(L),title(L=0),cursor(L),fade(F)]S+select_w_impl"
And the structure used should then be modified to something like this:
struct select_parm { enum select_parm_attrib attrib; union { int index; float fade_time; } attrib_parm; const char * value; };Note how additional storage space is NOT required. (Look at the union.)
select
/case
(and case default
) statements require a codegen implementation.
For now, this can be a simple generation of the equivalent if
/elseif
/else
chain. e.g.,
select name$
case "Bob": print "A Toyota's a Toyota."
case "Jack": print "Where's Jill?"
case "Alice": print "Wonderland's a wonderful place."
case "Jill": print "Did Jack fall down the hill again?"
case default: print "What kind of a name is " + chr$(34)+name$+chr$(34) + "?"
endselect
would be the equivalent of
if name$ = "Bob" : print "A Toyota's a Toyota."
elseif name$ = "Jack" : print "Where's Jill?"
elseif name$ = "Alice" : print "Wonderland's a wonderful place."
elseif name$ = "Jill" : print "Did Jack fall down the hill again?"
else : print "What kind of a name is " + chr$(34)+name$+chr$(34) + "?"
endif
See CSelectCaseStmt in StmtParser.cpp.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.