Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Topics - silenus

Pages: 1 [2] 3
Drivers / memory management fluffos
« on: September 01, 2009, 01:44:01 AM »
I have been playing around with the memory management routines in FluffOS and was looking for some general advice on how to go about perhaps removing certain block allocation behavior in the current system among other things. Testing with DeadSouls 2.10 I noticed that the system tends to like allocating data on my build in chunks of 200k-400k which is something i would like to avoid.

1) I am curious which subsystem (I am having difficulties tracing it in gdb) may be responsible for these block allocations (if anyone knows).

2) Also I am curious about the stralloc.c subsystem. I am thinking of replacing this as part of an experiment (with cords) but I am somewhat uncertain about how to test to see my changes aren't causing crashes. The problem is the cord library has specific instructions for handling concat, substr etc whereas stralloc.c returns char*. Is my best bet here to use a custom C++ ADT to wrap the interface in question and thus trap through the type system all the cstring type stuff including indexing via [].

Thanks in advance.

Drivers / Closures
« on: July 03, 2009, 02:18:16 AM »
I am currently thinking through anon function support for the driver I am working on. It's probably not as far along as the Terebi driver which Zod seems to be doing a good job with but progress in general has been good. I am debating currently about how best to implement anonymous functions and whether or not they should be allowed to access stack variables in the enclosing static scopes. I know ldmud support these but currently but fluffos does not. Is it a useful feature? I suspect it's significantly more work to implement since you need to have your semantic analysis determine which variables "escape" and require their stack frames(or elements of) to be places on the heap.

Drivers / class/structs and LPC
« on: March 17, 2009, 02:16:19 AM »

I have been trying to understand the class construct and it's exact role in LPC and the potential complications it causes and possible resolutions. My understanding is that the implementation of the class construct varies depending on the dialect of LPC and in some cases does not exist (dgd). LDmud implementation for example differs from FluffOS in that at the very least definitions are inherited from parents.

The fundamental problematic aspect of this type is that it's a name type where both the type information and structural information is erased after compilation with fluffos(i.e. it's converted into a mixed array). This results in some pretty nasty cast requirements and structural equivalence issues when dealing with call other while simple name equivalence is instead used when the definitions are compared within the same object. The situation is quite messy and perhaps why dgd decided not to include this user defined type mechanism into the dgd LPC variant.

For the driver I am working(if it ever sees the light of day) on I am quite tempted to drop this type for these reasons unless the problem or introducing type definitions can be resolved in some clean manner with name based semantics being preferred i.e. class A { int x } != class B { int x } even though they have the same structure. I suspect this problem cannot be resolved really without having some sort of "global" namespace where the user defined types can reside. Once you have multiple namespaces you will always run into some sort of problem. The difficulty here is LPC has no real global namespace for types. One idea maybe to extend the naming convention for programs based on the file name so that you can do stuff like filename%type1? to refer to a class outside it's original scope? The current solution in fluffos seems somewhat unacceptable IMHO(though maybe ppl have gotten use to it).

Design Lab / LPC++ toy
« on: March 02, 2009, 08:15:18 PM »
I have been thinking about changes to the basic LPC language for the new driver (relaunched?) project I have been working on and was curious about getting some input. I am currently working on the  type-checking and translation phases of the project so before things are more set in stone.... The main difference in the system would be a more extensive type system which supports a number of new types. The syntax for how all this would work is still up for grabs. The basic idea is to extend the type system to support records(read anonymous structs) and tuples (ala python) as well as simple recursive types as well as typing function variables + introducing pattern matching.

The price of all this is perhaps some new syntax and removal of certain features from current LPC to accomodate them. My suggested changes are as follows-

1) removal of the comma operator to accommodate tuples. (1,"string",4) would be a tuple return and could be used to return/assign multiple values.
2) abbreviate "({" to "[" and "([" to "{". According to my grammar thus far this change doesn't seem to create an ambiguity.
3) change declarations as follows [int] for arrays {int} for mappings introduce (int,string,int) for tuples and (label1: int, label2 : string) for records.
4) a function type (int,int) -> string for example
5) all for disjoint unions of types like in pike via string | int | float x; etc.
6) include a new labelling mechanism for types i.e. def x = type- allowing for old style classes and new style recursive types

now some of these changes are just a matter of taste. So obviously they can be reverted to a form which may be more LPC like. I.e. 2) can be backed out (obviously) and 3) & 4) might be possible to modify to make it more C like. i.e. use pike style array(int) and mapping(string,int) for example with functions being maybe string fun(int,int) f; though that might be difficult to parse.

Any comments would be appreciated.


Drivers / The strange world of mudos/fluffos scoping
« on: January 26, 2009, 05:10:40 AM »
Hi everyone,

I have been wondering about the following issue and how it is implemented in fluffos. The issue has to do with the interesting nature of the scoping rules when it comes to functionals and anonymous functions with one especially problematic case with the (: foo, arg1, arg2 :) syntax. The difficulty is that the "open scope" on the introduction of the anonymous function/functional behaves differently than a standard scope and hides effectively all variables in the preceeding scope unless it is in $() (where the new local definitions are completely hidden). The exception is of course the (: foo, arg1, arg2 :) syntax where it differentiates on the type of foo with foo being a declared function taking precedence.

 I have thought of a way to resolve this problem but I am curious how it's currently being done.

Thanks in advance,


Code Vault / modified /lib/props/inventory.c
« on: September 09, 2008, 03:26:59 PM »
This is more or less a drop in replacement for /lib/props/inventory.c. It has slightly different behavior- see the comments. Ignore the PERSISTENT ifdef stuff that is from some persistence code I have been working on and testing.

Code: [Select]
    Silenus - 2008/09/09
    a replacement for /lib/props/inventory.c

    It is slightly different from the DS version the main changes
    are with the arguments accepted in the SetInventory mapping.
    The following pairs are valid-

    <file> : <int>
    <file  : <function>
    <file> : <mapping>

    The first case is the same as the current common case behavior
    where the environment is checked for n items of base_name(<file>)
    and items are cloned until the number equals <int> again.

    The second case is almost the same as the first but <function>
    is evaluated to determine the quantity.

    The last case allows for some advance options to be set an includes
    the first two as special cases. The format of the mapping is-

    ([ "pre" : <function>, // pre-check return 1 if you want the object
                           // to load and 0 if not
       "post" : <function>, // function which allows you to customize the
                            // objects behavior after it has been moved into
                            // the environment
       "quantity" : <function>|<int> // same as for case 1 and 2
       "mobile" : <boolean> // determine if mobile tracking should be turned
                            // on. This changes the constraint from "quantity"
                            // objects in the room to "quantity" objects
                            // loaded  by the room which are still extant
                            // since the room was last updated

#include <daemons.h>

int isLoaded();


private mapping Loaded = ([]);
private static mapping Inventory = ([]);

static void eventLoadInventory();

static void eventLoadItem(string file, mixed args, int count);

mapping GetInventory()
    return copy(Inventory);

static void eventLoadItems(string file, mapping args)
    int n;
    object o;
    Loaded[file] = Loaded[file] - ({0});
    n = evaluate(args["quantity"]) - (args["mobile"] ? sizeof(Loaded[file]) :
        sizeof( filter( Loaded[file], (: environment($1) == $(this_object()) :) ) ) );
    for(int i = 0; i < n; ++i)
        if( file->GetUnique() && sizeof( filter( findobs(file), (: environment($1) :) ) ) )
        if( evaluate(args["pre"],n-i) )
            catch( o = new(file) );
                Loaded[file] += ({o});
                o->eventMove( this_object() );
                evaluate(args["post"],this_object(), n-i);
static void eventLoadInventory()
    foreach(string file, mixed args in Inventory)

mapping SetInventory(mapping m)
    string error;
    foreach(string k, mixed v in m)
        if( k[<2..] == ".c" )
            k = k[0..<3];
        if( k[0..0] != "/" )
            k = "/" + k;
        if( intp(v) || functionp(v) ) v = ([ "pre" : (: 1 :), "post" : (: 0 :), "quantity" : v, "mobile" : 0 ]);
        Inventory[k] = v; 
        Loaded[k] = ({});
    error = validate_mapping
               "pre" : "function",
               "post" : "function",
               "quantity" : (: (!functionp(v) || !intp(v) || v <= 0) ? "Value either not a function, not an integer, or less than 1." : 1 :),
               "mobile" : (: ((intp($1) && (v == 0 || v == 1)) ? 1 : "Value either 0 or 1") :)   
    if( stringp(error) ) error( error );
    if( !PERSIST_D->isLoading( this_object() ) && !isLoaded() )
    return copy(Inventory);

varargs void reset()

Code Vault / simple finite mapping type validation
« on: September 08, 2008, 07:13:42 AM »

This is some code I cooked up to perform simple mapping type validation for the most basic case where all the fields are fixed (though they can be nested). Perhaps it may be of use to someone...

Code: [Select]
// Silenus 2008-09-08
private int
_shallow_array_equals(mixed array ar1, mixed array ar2)
    return sizeof(ar1 - ar2) == 0 && sizeof(ar2 - ar1) == 0; 
private mixed
_validate(mapping m1, mapping m2, string array path)
    string error;
    if( !_shallow_array_equals( keys(m1), keys(m2) ) )
        return "*Keys in mapping do not match at level " + implode(path,"/") +
". Missing :" + implode( keys(m1) - keys(m2), ",") + "." +
        "Extra :" + implode( keys(m2) - keys(m1), ",") + ".";         
    foreach(mixed k, mixed v in m1)
        if( mapp(v) && stringp( error = _validate(v, m2[k], path + ({k}) ) ) )

            return error;
        else if( v != typeof( m2[k] ) )
            return "*Type mismatch for " + implode(path + ({k}) ,"/") +
". Expected: " + v + ", Got: " + typeof( m2[k] ) + ".";       
    return 1;

 Accepts a specification and data mapping and validates the data mapping
 conforms to the type specification specified by the specification. This
 procedure works for non-recursive (finite) specifications only.
            /* specification */
                ([ "name" : "string",
                   "hp" : "int",
                   "properties" :
                         "no attack" : "int",
                         "race" : "string"
                /* data */
            ([ "name" : "Silenus",
                   "hp" : "100",
                   "properties" :
                         "no attack" : "1",
                         "race" : "elf"
validate_mapping(mapping m1, mapping m2)
    return _validate(m1,m2,({}));

Design Lab / unification style pattern matching for LPC
« on: September 05, 2008, 01:19:52 PM »

While working on my driver project I have been considering possible "extensions" to the LPC language and sort of have a request for comments type document. The question is whether it would be meaningful to introduce unification style pattern matching in some form into LPC. This would in its most basic form result in the modification of two constructs which can be illustrate by the following code:

Code: [Select]
int factorial(int n)
    case 1: return 1;
    case n: return n*factorial(n-1);

switch(int n,string s)
   case 1, "silenus" : x = 1; break;
   case 1, "cratylus" : x = 2; break;

The idea is that this would involve mappings and arrays as well allowing for deep pattern matching i.e. something like

Code: [Select]
case ({x,y,({z,w})) : <use the variables here>

which would match something like ({1,2, ({3,4}) with x = 1, y = 2, z = 3 & w = 4 and so on. This could would also work with mappings where the keys would be considered as addresses and the values again pattern matched in this fashion. This could be made to apply to structs/classes in the same fashion.

I can already see some potential applications for this and a couple extensions which could make them more useful- but I am curious if anyone sees any promise in the basic idea of porting this notion from ML/Haskell etc into LPC.

Thanks in advance,


Drivers / Concurrent drivers
« on: August 10, 2008, 02:54:59 PM »
Does anyone know of any attempts to build drivers which support concurrency primitives? My understanding is from my limited research is there are three possible models which can be applied to tackle this sort of problem: 1) shared memory models 2) message passing models 3) transactional memory each of which has various strengths and shortcomings. My main concern with 1) is it tends to be the hardest for the programmer to get right and for 3) is that livelock/starvation situations can occur which stall progress completely. The nice thing however with both these approaches is they may be reasonably backward compatible with existing LPMud libraries.

This leaves 2). But the only language I know of which has these sorts of primitives is Erlang. The problem is that the language design is quite different than LPC which means that almost any design I can conceive of which resembles Erlang may not be that backwards compatible. Does anyone have any experience with other languages of this sort and if so how they install the message passing primitives in such a way that makes it backwards compatible with existing single process code with a clean semantics?

Thanks in advance,


Code Vault / MudOSish type grammar
« on: April 12, 2008, 02:54:28 PM »
Hi I am posting this portion of a project I am working on and have since abandoned- maybe it will be of some use to someone. It's a ANTLR v3 grammar file which generates ASTs and seems to parse MudOS LPC pretty well though there are some caveats and omissions and bugs. This was my first attempt at writing a moderate sized grammar with ANTLR so bear with me ;-). The code is licensed under GPLv3.

Code: [Select]
    Copyright Carter Cheng 2008

    This file is part of LPC on Java.

    LPC on Java is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    LPC on Java is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with LPC on Java.  If not, see <>.

grammar LPC;











@members {
public String getErrorMessage(RecognitionException e,
                               String[] tokenNames)
    List stack = getRuleInvocationStack(e, this.getClass().getName());
    String msg = null;
    if ( e instanceof NoViableAltException ) {
       NoViableAltException nvae = (NoViableAltException)e;
       msg = " no viable alt; token="+e.token+
           " (decision="+nvae.decisionNumber+
           " state "+nvae.stateNumber+")"+
           " decision=<<"+nvae.grammarDecisionDescription+">>";
    else {
       msg = super.getErrorMessage(e, tokenNames);
    return stack+" "+msg;
public String getTokenErrorDisplay(Token t) {
    return t.toString();

: declaration* EOF -> ^(FILE declaration*)

: inheritStatement
| dataDeclaration
| functionDeclaration
| classDeclaration

: t='inherit' StringLiteral ('+' StringLiteral)* ';' -> ^(DECL_INH[$t] StringLiteral+)

: (modifier)* type dataDeclarator (',' dataDeclarator )* ';' -> dataDeclarator+

: m=(modifier)* t=funType p=('*')? Identifier '(' formalArguments? ')' ( ';'-> ^(DECL_FUN $t $m* Identifier formalArguments?) | block ->^(DECL_FUN $t $m* Identifier formalArguments? block) )

: t='class' Identifier '{' classDataDeclaration* '}' -> ^(DECL_CLASS[$t] Identifier classDataDeclaration*) 

: p=('*')? Identifier ('=' constantExpression )? -> ^(DECL_DATA $p? Identifier constantExpression?)

: formalArgument (',' formalArgument )* e=('...')? -> ^(FORMALS $e? formalArgument+)

: type p=('*')? Identifier? -> ^(FORMAL type $p? Identifier?)

block   : t='{' (statement)* '}' -> ^(BLOCK[$t] statement*)

: type p=('*')? Identifier (',' ('*')? Identifier)* ';' -> ^(DECL_CLASS_DATA type $p? Identifier)

: block -> block
| type varDeclarator (',' varDeclarator )* ';' -> varDeclarator+
| expression ';'
| t='if' '(' expression ')' statement ( ('else')=> 'else' statement)? -> ^(IF[$t] expression statement+)
| t='switch' '(' expression ')' '{' switchBlockStatementGroup* '}' -> ^(SWITCH[$t] expression switchBlockStatementGroup*)
| t='while' '(' expression ')' statement -> ^(WHILE[$t] expression statement)
| t='do' statement 'while' '(' expression ')' ';' -> ^(DO_WHILE[$t] expression statement)
| t='for' '(' forInit? ';' expression? ';' expressionList? ')' statement -> ^(FOR[$t] ^(INIT forInit?) ^(COND expression?) ^(ITER expressionList?) statement)
| t='foreach' '(' ( type ('*')?)? Identifier (',' ( type ('*')?)? Identifier )? 'in' expression ')' statement -> ^(FOREACH[$t] expression statement)
| t='continue' ';' -> ^(CONTINUE[$t])
| t='break' ';' -> ^(BREAK[$t])
| t='return' expression? ';' -> ^(RETURN[$t] expression?)
| ';' -> ^(EMPTY_STMT)

:   switchLabel statement* -> ^(BLOCK_GROUP switchLabel statement*)

:   'case' constantExpression ( '..' constantExpression)? ':'
|   'default' ':'

: type varDeclarator (',' varDeclarator )* -> ^(DECL_VARS varDeclarator+)
| expressionList -> expressionList

: p=('*')? Identifier ('=' expression)? -> ^(DECL_VAR $p? Identifier expression?)

: assignmentExpression -> ^(CONST assignmentExpression)

: assignmentExpression (','^ assignmentExpression )*

: (conditionalExpression -> conditionalExpression)  (o=assignmentOperator e=assignmentExpression -> ^($o $assignmentExpression $e) )?

: '='
| '*='
| '/='
| '%='
| '+='
| '-='
| '<<='
| '>>='
| '&='
| '^='
| '|='

: (logicalOrExpression -> logicalOrExpression) (o='?' e1=expression ':' e2=conditionalExpression -> ^($o $conditionalExpression $e1 $e2)  )?

: logicalAndExpression ('||'^ logicalAndExpression )*

: inclusiveOrExpression ('&&'^ inclusiveOrExpression )*

: exclusiveOrExpression ('|'^ exclusiveOrExpression )*

: andExpression ('^'^ andExpression )*

: equalityExpression ('&'^ equalityExpression )*
: relationalExpression ( ('=='^|'!='^) relationalExpression )*

: shiftExpression ( ('<'^|'>'^|'<='^|'>='^) shiftExpression )*

: additiveExpression ( ('<<'^|'>>'^) additiveExpression )*

: multiplicativeExpression ( ('+'^|'-'^) multiplicativeExpression )*

: unaryExpression ( ('*'^|'/'^|'%'^) unaryExpression )*

: '(' type p=('*')? ')' unaryExpression -> ^(CAST type $p? unaryExpression)

    :   unaryOperator unaryExpression -> ^(unaryOperator unaryExpression)
|   castExpression -> castExpression
|   primaryExpression selector* o=('++'|'--')? -> ^(PRIMARY primaryExpression selector* $o?) 

: '+'
| '-'
| '++'
| '--'
| '~'
| '!'

: '(' (argumentExpressionList -> argumentExpressionList| -> ^(ARGS) ) ')'

: assignmentExpression (',' assignmentExpression)* e=('...')? -> ^(ARGS $e? assignmentExpression+)

: t='[' i1=indexExpression (('..' i2=(indexExpression)? ) -> ^(RANGE[$t] ^(BEGIN $i1) ^(END $i2?) ) | -> ^(INDEX[$t] $i1) ) ']'   
| t='[' '..' indexExpression ']' -> ^(RANGE[$t] ^(BEGIN) ^(END indexExpression) )
| t='->' Identifier (arguments -> ^(CALL_OTHER[$t] Identifier arguments) | -> ^(FIELD Identifier) )

: p=('<')? expression -> ^(INDEX_EXPR $p? expression)

: literal -> ^(CONST literal)
| Identifier -> ^(VAR Identifier)
| functionName arguments -> ^(CALL functionName arguments)
| '(' expression ')' -> expression
| t='$' '(' expression ')' -> ^(LAMBDA_CONST[$t] expression)
| t='catch' '(' expression ')' -> ^(CATCH[$t] expression)
| t=LambdaExpressionVariable -> ^(LAMBDA_VAR[$t] LambdaExpressionVariable)
| t='(' '{' (expressionList)? '}' ')' -> ^(VAR_ARRAY[$t] expressionList?)
| t='(' '[' (keyValueList)? ']' ')'-> ^(VAR_MAP[$t] keyValueList?)
| t='(' ':' expressionList ':' ')' -> ^(LAMBDA_EXPR[$t] expressionList)
| funType p=('*')? t='function' '(' formalArguments? ')' block -> ^(VAR_FUN[$t] ^(TYPE funType $p?) formalArguments? block)
| t='new' '(' (('class' Identifier) -> ^(VAR_CLASS[$t] Identifier) | expression -> ^(VAR_OBJECT[$t] expression) ) ')'

: ('::')? Identifier ('::' Identifier)?

: assignmentExpression (',' assignmentExpression )* -> ^(EXPR_LIST assignmentExpression+)

: keyValue (',' keyValue )* -> ^(ELEMENT_LIST keyValue+)

: assignmentExpression ':' assignmentExpression -> ^(ELEMENT assignmentExpression assignmentExpression)

: 'public'
| 'private'
| 'protected'
| 'static'
| 'nosave'
| 'nomask'
| 'varargs'

: basicType ('array')?
| 'mapping'

: 'void'
| type

: 'int'
| 'float'
| 'string'
| 'function'
| 'object'
| 'mixed'
| 'class' Identifier

: '$' ('1' .. '9') ('0' .. '9')*

: Letter (Letter | '0' .. '9' )*

: '_'
| 'a' .. 'z'
| 'A' .. 'Z'

: CharLiteral
| DecimalLiteral
| HexLiteral
| OctalLiteral
| FloatLiteral
| StringLiteral

    :   '\'' ( EscapeSequence | ~('\''|'\\') ) '\''

: ('0' | '1'..'9' '0'..'9'*)

: '0' ('x'|'X') ('0'..'9'|'a'..'f'|'A'..'F')+

: '0' ('0'..'7')+

:   Digit+ '.' Digit+ Exponent? FloatTypeSuffix?
|   '.' Digit+ Exponent? FloatTypeSuffix?

: ('0'..'9')

    :   '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')

Exponent : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;

FloatTypeSuffix : ('f'|'F'|'d'|'D');

:  '"' ( EscapeSequence | ~('\\'|'"') )* '"'

WS  :  (' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;}

    :   '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}

    : '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}

// ignore #line info for now
    : '#' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}

Design Lab / New drivers and the nature of self.
« on: March 24, 2008, 01:03:49 PM »
Hello everyone,

I am not sure if there is much interest in this but I am currently working on a new driver written in Java embedding the language Self 4.1 or something quite close to it though most likely it will not have the same primitives (efuns) since the set of these functions for Self 4.1 seems rather extensive and the associate World code quite large. The design of the remainder of the driver is currently planned to be decidedly LPish in nature. There will be things like a driver object some sort of object similar to the auto dgd object (though perhaps connecting to it will be voluntary) and so on. The mud system will have some of the following features-

It will be fileless- everything will be stored directly in the system- essentially a large persistent store. I am still debating the issue of builtin security. If the system were to have such a thing it would be based around an access control list type system where each object has a set of roles which determine it's privileges. Permissions could be either fine grain on a per slot( read function/variable ) basis or course grained on a per object basis. There is still probably alot to figure out- optimization of persistence is probably the biggest issue but I am hoping to hear some opinions on how best to construct a current generation mud system.   

Design Lab / Generics in LPC
« on: February 23, 2008, 02:09:27 PM »
Hi everyone,

Thanks for all the responses so far they have been helpful. I do have another query though would stuff like generics (2nd order types or parametric polymorphism) make any sense in a language like LPC? I see some things that possibly could be solved more elegantly with them but also some problems because certain things in LPC have rather complex type structures and are essentially untyped.

C++/Java/C# all support type parameters and I was wondering if it would be meaningful to add this notion to LPC somehow.

There ideas are pretty embryonic but here goes for functions add a type parameter and have * as a default type parameter so something like filter would be defined as follows:

U array filter<U>(U array arr, (U)->int fun)
      U array results = ({});
      foreach(U elem in arr)
            if( evaluate( fun, elem ) ) results += ({ elem });
      return results;

where U is a place holder for int, float, string etc. The problem i see with this atm is that because of stricter typing untyped (: :) would have to be coerced to the proper type or everything else coerced into a mixed to match the definition. Also the annotations are a bit on the arcane side for those not familiar with the idea. Would appreciate hearing peoples thoughts.

Design Lab / Stronger static typing in LPC
« on: February 21, 2008, 07:53:30 AM »
Hi everyone,

I am debating the merits of adding stronger static typing to LPC and perhaps some other minor enhancements/modifications to the basic LPC specification while trying to remain as close to backwards compatible as possible. My thoughts are that function and mapping variables rather than being ([ mixed : mixed ]) and mixed function(mixed...) respectively always should have some sort of type structure. The problem is finding some sort of syntax for this. I had originally considered discarding alot of the trappings of LPC syntax to get these results but I am worried that the resulting "new syntax" would be too foreign to most people.

My thoughts on this originally were as follows-

replace mapping m; with something like ([ string : int ]) m;

replace function f; with something like (int, int)->string f;

and perhaps replacing int array a or int *b with something like ({int}) c;

The idea behind this scheme is to get better type checking; so the compiler and runtime system can report errors if you attempt to stuff say a object key into a string key mapping or attempt to call an anonymous function which accepts (int a,int b) with a string argument or anything other than two integer arguments. Anyone have any thoughts on this?

Thanks again,



Design Lab / LPC on java/.net or C?
« on: February 15, 2008, 01:59:42 PM »
I am currently embarking on an attempt to create something that resembles a lpc mud driver. So far what I have in hand is an ANTLR grammar that for the most part accepts the MudOS variant of LPC (it seems to parse most DS files without problems there are a few exceptions). The question I have for the others is what sort of platform to target.

There are a few options:

1) Java (sandboxing + classloaders and implement call other via reflection)

2) .NET (similar capabilities with assemblies which can support lambdas better but might be less secure)

3) C (suggested by someone else) using dynamic loading.

4) something else Parrot (is it mature enough?) LLVM(can this handle dynamic loading well?)

Would be interested to hear everyones thoughts.



Design Lab / design of lambda for dgd
« on: January 24, 2008, 02:07:50 PM »
I am currently trying to build a lambda functions type module on top of dgd and this is a call for features sort of for such a module. It's part of a language extensions package I have planned for dgd LPC which will include (hopefully) stuff like reflection capabilities and metaprogramming features among other things.

For the lambda system my idea is not to go with something that looks exactly like anonymous function pointers in mudos LPC but something that exploits some of the features of dgd compile_object and lwo's better. Basically I would like to see three additional things.

1) a more elegant function argument signature syntax which allows passing of arguments into the lambda expression in a more succinct manner. Currently Mudos has two syntaxes the function(x,y) syntax and the (: :) syntax. I would prefer one syntax that captures both cases.

2) a means of decompiling and converting function objects so they can be examined more easily and augmented and recompiled ala continuations in an efficient manner. This is actually a bunch of related ideas. But the general idea is that it should be possible to inspect the contents of an anonymous lambda object and determine what it does with minimal fuss on the one hand and for efficiency reasons make continuations possible through recompilations rather than having a series of linked lwo objects.   

3) closure variables which are sort of like object variables which are preserved between calls. I am really unsure about a syntax for this which meshes with LPC well. but i suspect this feature would be quite desirable since you could create co-routine like yield behavoir.

Thanks for any input.


Pages: 1 [2] 3