Archive for October, 2008

Type limits

Thursday, October 30th, 2008

So I went in and added the most basic data-driven type system and all was good…until I realized there is no elegant way to define value limits. For instance if you wanted the valid value of a key to be a floating point between 0 and 1, you’re out of luck. It can only say it’s a float (by matching a regular expression). It doesn’t even know it’s a numeric value.

So I have to add numeric types to the type definitions, at least. But, only allowing limits in type definitions would be cumbersome. Imagine having to use types like float_0_1. Actually, that’s not completely terrible, but I would desperately enjoy a shorthand range syntax. Then I don’t have to go around creating tonnes of type definitions with slightly different value limits.

Type definitions still have their uses, though. Like, I don’t know, if you wanted to make sure all your integer values could fit into 16-bits, you could define a custom type called ‘myint’ (or maybe I’ll allow the built-in type ‘int’ to be redefined!) and give it the appropriate limits (−32768,32767) and use it throughout your data definitions. Then one day you decide 32-bits is where it’s at, and you can just change the limits on ‘myint’ and you’re done!

So, there will be built-in primitive types after all and shorthand value range syntax. Not so bad I guess. I suppose the types will end up being something like: string, int, float, float2, float3, float4 with some kind of range syntax. Then I can go around saying things like: float(0,1). Hmm, I’m still undecided…

Progress

Wednesday, October 29th, 2008

After finishing up the core UDL parser I found it was extremely simple to use the core language to define schema for type checking. Right now UDL can parse a config and roughly check it against a schema (it only checks that names are correct and keys have the correct number of values). It’s functional but not very robust. No error messages, etc.

While I was finishing up the schema stuff I started thinking about how I wanted to handle the actual type checking of values. I originally planned to have primitive types basically hard coded into UDL itself, so you could say a given value was an int, float or whatever. This isn’t very flexible since you have to write code if you want to add a new type. My plan now is to provide a very simple API for adding new type checkers. Once that’s in it should be a simple matter to drive it by some simple UDL definitions! Allowing new types without new code will be really great! I hope it works out.

UDL core language updates

Wednesday, October 22nd, 2008

There were some features missing from the original UDL core language that I wanted to address. Some of the new features include keys with no values and quoted names for key and section names. However, the most important new feature is an new syntax for specifying key values over multiple lines.

Previously, if you wanted a key with 100 values you had to put them all on one line. This is both inconvenient to write out and hard to read. The simple and elegant solution is the addition of a multi-line key syntax. In this example both definitions of the key ‘data’ are equivalent.

[example "some name"]
{
  UseSystemMemory
  "Key String" "some string"
  data 1 2 3 4 5 6 7 8 9 0 11 12 13 14 15
  data
  {
     1  2  3  4  5
     6  7  8  9 10
    11 12 13 14 15
  }
}

Originally, I had been considering introducing a new type beyond keys and sections for specifying large amounts of data. This would have required a completely new data type, complicating the language and resulting API. Multi-line key syntax only requires a change to the parser. In addition any key can be specified on multiple lines using this syntax if it’s convenient for the user.

With these updates the grammar of UDL is now:

file        : sections
            | empty

sections    : section
            | section sections

section     : "[" value value "]" NEWLINE "{" statements "}" NEWLINE

statements  : statement
            | statement statements

statement   : section
            | keys

key         : value NEWLINE
            | value values NEWLINE
            | value NEWLINE "{" value_lines "}" NEWLINE

values      : value
            | value values

value_lines : values NEWLINE
            | values NEWLINE value_lines

value       : NAME
            | STRING

Of comments and semicolons

Friday, October 17th, 2008

I finished the last few features of the UDL core language: comments and semicolons. Comments affect the lexer while semicolons affect the parser.

Comments are simple C-style single and multi-line comments. The lexer just skips right over them and they don’t make it to the parser.

Semicolons are used to break up keys on a single line allowing multiple keys per line. It also makes it convenient to specify an entire section on one line if necessary.

/*
Example object (
*/
[object example]
{
  // multiple keys on a line
  Texture textures/default.tga; Size "512 512"

  // single line section
  [Uniforms] { Color "1 1 0 1"; Offset "0.5 0.5" }
}

While neither of these features is particularly earth shattering they do fill out the usefulness of the language. Now it’s time to focus on converting my old python UDL parser into a simple UDL C Api.