Streak Club is a place for hosting and participating in creative streaks.
So in the past few days I've been working at getting backend variables working nicely with the compiler. The gist of how it works is that if it detects a backend variable (variables prefixed with a $ sign) in a loop/if/whatever else, then it switches how the code is compiled. Basically the HTML output will wrap child nodes between <?php if (isset($myvar) && $myvar) { ?> and <?php } ?>.
You can also pass-in backend variables to components and get them to modify the attributes of that component and that components sub-components, which I thought was really cool.
This coming week will most likely be just me fixing a few issues with how backend variables are handled. Next, I'll be looking into allowing component names to be referenced in 'style' blocks.
Today I got the 'loop' keyword basics working. So now on layout items you can do 'loop 2' or any number really, and it will repeat that layout content that many times. Now this isn't super useful in production but when you want to test a slideshow/navigation/carousel layout, it's great for quickly repeating yourself.
I also discovered a bug with how child elements are inserted with the 'children' keyword. Basically I needed to duplicate a components 'layout' block in memory or else the cached copy of the compilation would break across the entire codebase.
I lost a bit of my streak there eh?
Yesterday, I got 'else/else if' cases compiling properly. Today I started on implementing the 'loop' keyword, which will essentially act as a 'foreach' for looping over an array or allow counted iterations, ie. 'loop 2' will render the layout items twice.
Before I can do something like 'loop $Posts as $Post', I decided to implement simple echoing of backend variables in the layout, which is done much like Silverstripe, simply with '$Varname'.
I've also got a side project to this, which is a mobile-touch editor for Game Maker rooms. This editor will be built into the GM code and auto-read objects to place so you might see a few posts about that too.
Today on my lunch break I fixed the passing component variables into sub-components problem. I did that by passing in the parent_component to the compileComponent function.
Today I spent a couple of hours getting the HTML classes and CSS outputted to be optimal. The styling is now diff'd between parameterized components and base components so that there's no doubling up and HTML classes are only applied based on whether variables were read from in the 'styles' block which is helping make the HTML a lot cleaner.
In the midst of this I've noticed that 'attributes' have become broken, but I'll either rectify that tonight or tomorrow. For now, immediate future goals will be parsing selectors better so you can reference components and adding caching mechanisms for parsing and compiling.
I renamed some variables to help me remember what type they are. (No strict typing PHP, yayyy) Got a concert tonight, The Antlers in Melbourne, so not enough time today to get real work done!
Today I added strict typing to some functions and modified how 'compileCodeBlock' returns information. It can now tell me what variables were read from during execution, something which I plan to use to diff between selectors for optimizing the CSS output.
Today and yesterday have been minor tweaks to making sure the compiler is working properly under the hood. Yesterday I fixed newlines breaking expressions parsing and got CSS blocks to resolve variables properly, since I didn't implement that.
Today I didn't really feel like doing much, so I took up the task of fixing an outstanding bug with the lexer, where something like:
if (expression { }
Would throw an error inside the lexer. So I modified my lexer to make sure that this was properly tokenized and handled nicely by the parser.
Enums are now implemented! Unfortuantely right now they aren't evaluated so you can't do anything like:
enum Colors { primary = 30 + 10 + 50, }
But static values single values work fine.
enum Colors { primary = #ff0000, secondary = #00ff22, tertiary = #2b00ff, }
As far as variable scope goes, if you have a variable called 'Colors' then you won't be able to use the enum, and there is no special 'global' keyword or anything yet.
I've also just realized that you couldn't use enums within the layout due to it using a capital letter, so I think I need to rethink how component definitions work and possibly work towards components not needing to have an uppercase first letter.
Phew, ok. Today I sat down for roughly less than 30 mins to work on my compiler but I got the basics of object-based tokens working. So now code like 'children.count' will properly evaluate the variables of the object 'children' whereas previously, 'children.count' was stored in the assoc. array directly.
This is in preparation again for enumerators.
I've been out most the afternoon but I got a lot done in the morning and a bit done tonight. I cleaned up my lexer so that it finally processes CSS selectors and keywords properly. This had to be done in preparation for the next feature I want to add to the language, enums!
As I'm building a site and making up features as I go along, I realized I needed a method to easily manage global constant variables. I decided on enums as I always liked the concept of putting a few constants inside a neat little namespace.
Adding enums will require me to rethink how my current compilation of expressions works, as scope matters more than it did in the past.
Ahh damn, haven't posted in 3 days but TECHNICALLY speaking I only really missed yesterday, that's a bit disappointing. In any case, I've got child nodes working! You can now place components within components which I think is really neat. The perfect example of where you might want this is the typical navigation dropdown dropdown pattern(1). Instead of having a UL inside your first level LI tag, your code would just be something like this:
Nav { Nav_Item(label = "Home", source = "<a href="http://<a href=" http:="" <a="">www.google.com</a>">www.google.com">www.google.com") { } Nav_Item(label = "About Us", source = "www.google.com") { Nav_Item(label = "What We Do", source = "www.yahoo.com") { } } Nav_Item(label = "Contact Us", source = "www.google.com"); }
The actual components used in this layout however, are defined as so:
def Link { attributes { element = "a"; href = source; } variables { source = ""; } } def Nav { attributes { element = "ul"; class = "nav"; } styles { self { list-style: none; margin: 0; padding: 0; } } } def Nav_Section { attributes { element = "ul"; class = "nav-sub"; } styles { self { position: relative; left: 0; top: 0; display: none; width: 100%; margin: 0; padding: 0; } } } def Nav_Item { attributes { element = "li"; class = "nav-item"; } variables { label = ""; source = ""; } styles { self { position: relative; } // todo(SW): replace .nav-sub with ability to just use component names // ie. self:hover > Nav_Section self:hover > .nav-sub { display: block; } } layout { self { Link(source = source) { // use 'label' variable label; } // Only display these sub-elements if I have children if (children.count) { Nav_Section { children; } } } } }
As you can see, this has the capability to abstract your code in a much neater way as well as coupling your HTML and CSS closer together.
(1) http://osvaldas.info/drop-down-navigation-responsi...
Today on my lunch break I was quickly able to implement "else" and "else if" statements for compilation. Something that I had been putting off because of other more important features. I was really surprised that it only took 20-30 minutes to get working, though at the moment the implementation isn't bullet-proof and could probably get a bit wonky with nested if-statements. Oh well, the base code is in there at least :)
More progress today! You can finally use the 'layout' block for components which is absolutely awesome for reusability and keeping layout code clean and concise.
As a bit of a break, I decided to spend a bit of the night looking into SNES assembly since I've always wanted to build a SNES game for nostalgic reasons, so far I've got a green screen so at least I've made a start!
Ah! I missed posting yesterday!
No problem though, I promise I actually did some more work on the compiler. I unfortunately wasted a bit of time trying to design how my code generation would work instead of just getting stuck into the code and re-factoring later.
Today (so far) I've gotten variables from components passing into the sub-components used for the layout, which is really neat! My next goal will be to hopefully get my code generation working again with this new system! Then I'll continue building a website to see what other features would be nice for web development.
Not much to report on tonight. I made a start on allowing components to also contain components in their layout but nothing major, also added in multi-line commenting because I was lazy with my lexer and didn't bother, but that's been fixed now.
Anyway, it's FRIDAY. Woo.
Lots of work done tonight. I can actually see the resulting HTML/CSS output of my components/layout! At the end of my coding session when I started to play around with the language, I realized it was desperately lacking components using components for the layout so hopefully tomorrow night I can rectify that.
Code:
http://pastebin.com/1UuHjfcG
Compiles to:
http://pastebin.com/5eD33hEM
Not much was done today, I made a start on code generation and the HTML and CSS generated is looking good. Unfortunately attributes defined in the components aren't being passed across to the code generation system properly but I should hopefully have that rectified by tomorrow night.
I'm hoping that far into the future when everything is at an acceptable level, building a website will be simpler with better error reporting. ie. If you set a min-height on a <table> element, it tells you off. (Because as everyone knows, <table> only accepts height and height acts like min-height)
As of late I've been working on a compiler for a new type of HTML/CSS that helps couple the two together better but still in a reusable and simple way.
Today I spent 30 mins on my work lunch break working on component caching, which will help the compiler to only output the CSS once.
daily from
Best streak: 5, Completion: 5%