mirror of
https://github.com/gnustep/libs-steptalk.git
synced 2025-02-16 00:11:29 +00:00
added actor class
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/steptalk/trunk@21382 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
2e2d056a79
commit
e06f7bf374
8 changed files with 332 additions and 7 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,4 +1,13 @@
|
|||
2005 Jul 19 Stefan Urbanek
|
||||
2005 June 30
|
||||
|
||||
* STActor: new class
|
||||
* Examples/Smalltalk/actor - new actor example
|
||||
|
||||
2005 June 19
|
||||
|
||||
Version 0.9.0
|
||||
|
||||
2005 June 19 Stefan Urbanek
|
||||
|
||||
* STEnvironment: search class name namespace when no object is found for
|
||||
given name and full scripting is enabled.
|
||||
|
|
48
Examples/Smalltalk/actor.st
Normal file
48
Examples/Smalltalk/actor.st
Normal file
|
@ -0,0 +1,48 @@
|
|||
| actor engine source method |
|
||||
|
||||
actor := STActor actorInEnvironment:Environment.
|
||||
"Set ivars"
|
||||
|
||||
ivars := NSMutableDictionary dictionary.
|
||||
ivars setObject:1 forKey:'number'.
|
||||
actor setInstanceVariables:ivars.
|
||||
|
||||
" Get the proper engine "
|
||||
engine := STEngine engineForLanguageWithName:'Smalltalk'.
|
||||
|
||||
" This is the source of new method "
|
||||
source := 'increment
|
||||
number := number + 1. ^self'.
|
||||
|
||||
" Create method "
|
||||
method := engine methodFromSource:source
|
||||
forReceiver:actor
|
||||
inEnvironment:Environment.
|
||||
|
||||
" Add the method to the actor "
|
||||
actor addMethod:method.
|
||||
|
||||
" Add another method with an argument "
|
||||
source := 'setNumber:i number := i. ^self'.
|
||||
method := engine methodFromSource:source
|
||||
forReceiver:actor
|
||||
inEnvironment:Environment.
|
||||
actor addMethod:method.
|
||||
|
||||
source := 'print
|
||||
Transcript showLine: (\'The number is \',
|
||||
(number description)). ^self'.
|
||||
method := engine methodFromSource:source
|
||||
forReceiver:actor
|
||||
inEnvironment:Environment.
|
||||
actor addMethod:method.
|
||||
|
||||
" Send it! "
|
||||
actor print.
|
||||
actor increment.
|
||||
actor print.
|
||||
actor increment.
|
||||
actor print.
|
||||
actor setNumber:10.
|
||||
actor print.
|
||||
|
|
@ -27,6 +27,7 @@ FRAMEWORK_NAME = StepTalk
|
|||
|
||||
StepTalk_OBJC_FILES = \
|
||||
NSInvocation+additions.m \
|
||||
STActor.m \
|
||||
STBehaviourInfo.m \
|
||||
STBundleInfo.m \
|
||||
STClassInfo.m \
|
||||
|
@ -58,6 +59,7 @@ StepTalk_OBJC_FILES = \
|
|||
# STDistantEnvironment.m \
|
||||
|
||||
STEPTALK_HEADER_FILES = \
|
||||
STActor.h \
|
||||
STBundleInfo.h \
|
||||
STContext.h \
|
||||
STConversation.h \
|
||||
|
|
44
Frameworks/StepTalk/STActor.h
Normal file
44
Frameworks/StepTalk/STActor.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
/**
|
||||
STActor
|
||||
StepTalk actor
|
||||
|
||||
Copyright (c) 2002 Free Software Foundation
|
||||
|
||||
Written by: Stefan Urbanek <urbanek@host.sk>
|
||||
Date: 2005 June 30
|
||||
License: LGPL
|
||||
|
||||
This file is part of the StepTalk project.
|
||||
*/
|
||||
|
||||
#import <Foundation/NSObject.h>
|
||||
|
||||
#import "STMethod.h"
|
||||
|
||||
@class NSMutableDictionary;
|
||||
@class NSDictionary;
|
||||
@class NSArray;
|
||||
@class STEnvironment;
|
||||
|
||||
@interface STActor:NSObject<NSCoding>
|
||||
{
|
||||
NSMutableDictionary *ivars;
|
||||
NSMutableDictionary *methodDictionary;
|
||||
|
||||
STEnvironment *environment;
|
||||
}
|
||||
+ actorInEnvironment:(STEnvironment *)env;
|
||||
- initWithEnvironment:(STEnvironment *)env;
|
||||
- (void)setEnvironment:(STEnvironment *)env;
|
||||
- (STEnvironment *)environment;
|
||||
|
||||
- (void)setObject:(id)anObject forVariable:(NSString *)aName;
|
||||
- (id)objectForVariable:(NSString *)aName;
|
||||
|
||||
- (void)addMethod:(id <STMethod>)aMethod;
|
||||
- (id <STMethod>)methodWithName:(NSString *)aName;
|
||||
- (void)removeMethod:(id <STMethod>)aMethod;
|
||||
- (void)removeMethodWithName:(NSString *)aName;
|
||||
- (NSArray *)methodNames;
|
||||
- (NSDictionary *)methodDictionary;
|
||||
@end
|
221
Frameworks/StepTalk/STActor.m
Normal file
221
Frameworks/StepTalk/STActor.m
Normal file
|
@ -0,0 +1,221 @@
|
|||
/**
|
||||
STActor
|
||||
StepTalk actor
|
||||
|
||||
Copyright (c) 2002 Free Software Foundation
|
||||
|
||||
Written by: Stefan Urbanek <urbanek@host.sk>
|
||||
Date: 2005 June 30
|
||||
License: LGPL
|
||||
|
||||
This file is part of the StepTalk project.
|
||||
*/
|
||||
|
||||
#import "STActor.h"
|
||||
|
||||
#import "NSInvocation+additions.h"
|
||||
#import "STEngine.h"
|
||||
#import "STExterns.h"
|
||||
#import "STObjCRuntime.h"
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSCoder.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSException.h>
|
||||
#import <Foundation/NSInvocation.h>
|
||||
#import <Foundation/NSString.h>
|
||||
|
||||
@implementation STActor
|
||||
/** Return new instance of script object without any instance variables */
|
||||
+ actorInEnvironment:(STEnvironment *)env
|
||||
{
|
||||
return AUTORELEASE([[self alloc] initWithEnvironment:env]);
|
||||
}
|
||||
+ actor
|
||||
{
|
||||
return AUTORELEASE([[self alloc] init]);
|
||||
}
|
||||
- init
|
||||
{
|
||||
self = [super init];
|
||||
methodDictionary = [[NSMutableDictionary alloc] init];
|
||||
ivars = [[NSMutableDictionary alloc] init];
|
||||
return self;
|
||||
}
|
||||
- initWithEnvironment:(STEnvironment *)env;
|
||||
{
|
||||
self = [self init];
|
||||
[self setEnvironment:env];
|
||||
|
||||
return self;
|
||||
}
|
||||
- (void)dealloc
|
||||
{
|
||||
RELEASE(methodDictionary);
|
||||
RELEASE(ivars);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)setValue:(id)value forKey:(NSString *)key
|
||||
{
|
||||
/* FIXME: this is not optimal */
|
||||
if([ivars valueForKey:key] != nil)
|
||||
{
|
||||
[ivars setValue:value forKey:key];
|
||||
}
|
||||
else
|
||||
{
|
||||
[super setValue:value forKey:key];
|
||||
}
|
||||
}
|
||||
- (id)valueForKey:(NSString *)key
|
||||
{
|
||||
id value = nil;
|
||||
|
||||
value = [ivars valueForKey:key];
|
||||
|
||||
if(value == nil)
|
||||
{
|
||||
value = [super valueForKey:key];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
- (NSArray *)instanceVariableNames
|
||||
{
|
||||
return [ivars allKeys];
|
||||
}
|
||||
- (void)setInstanceVariables:(NSDictionary *)dictionary
|
||||
{
|
||||
[ivars removeAllObjects];
|
||||
[ivars addEntriesFromDictionary:dictionary];
|
||||
}
|
||||
- (NSDictionary *)instanceVarables
|
||||
{
|
||||
return [NSDictionary dictionaryWithDictionary:ivars];
|
||||
}
|
||||
- (void)addMethod:(id <STMethod>)aMethod
|
||||
{
|
||||
[methodDictionary setObject:aMethod forKey:[aMethod methodName]];
|
||||
}
|
||||
- (id <STMethod>)methodWithName:(NSString *)aName
|
||||
{
|
||||
return [methodDictionary objectForKey:aName];
|
||||
}
|
||||
- (void)removeMethod:(id <STMethod>)aMethod
|
||||
{
|
||||
[self notImplemented:_cmd];
|
||||
}
|
||||
- (void)removeMethodWithName:(NSString *)aName
|
||||
{
|
||||
[methodDictionary removeObjectForKey:aName];
|
||||
}
|
||||
- (NSArray *)methodNames
|
||||
{
|
||||
return [methodDictionary allKeys];
|
||||
}
|
||||
- (NSDictionary *)methodDictionary
|
||||
{
|
||||
return [NSDictionary dictionaryWithDictionary:methodDictionary];
|
||||
}
|
||||
/** Set object's environment. Note: This method should be replaced by
|
||||
some other, more clever mechanism. */
|
||||
- (void)setEnvironment:(STEnvironment *)env
|
||||
{
|
||||
ASSIGN(environment, env);
|
||||
}
|
||||
- (STEnvironment *)environment
|
||||
{
|
||||
return environment;
|
||||
}
|
||||
- (BOOL)respondsToSelector:(SEL)aSelector
|
||||
{
|
||||
if( [super respondsToSelector:(SEL)aSelector] )
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
return ([methodDictionary objectForKey:NSStringFromSelector(aSelector)] != nil);
|
||||
}
|
||||
|
||||
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel
|
||||
{
|
||||
NSMethodSignature *signature = nil;
|
||||
|
||||
signature = [super methodSignatureForSelector:sel];
|
||||
|
||||
if(!signature)
|
||||
{
|
||||
signature = STConstructMethodSignatureForSelector(sel);
|
||||
}
|
||||
|
||||
return signature;
|
||||
}
|
||||
|
||||
- (void) forwardInvocation:(NSInvocation *)invocation
|
||||
{
|
||||
STEngine *engine;
|
||||
id <STMethod> method;
|
||||
NSString *methodName = NSStringFromSelector([invocation selector]);
|
||||
NSMutableArray *args;
|
||||
id arg;
|
||||
int index;
|
||||
int count;
|
||||
id retval = nil;
|
||||
|
||||
method = [methodDictionary objectForKey:methodName];
|
||||
|
||||
if(!method)
|
||||
{
|
||||
[NSException raise:@"STActorException"
|
||||
format:@"No script object method with name '%@'",
|
||||
methodName];
|
||||
return;
|
||||
}
|
||||
|
||||
engine = [STEngine engineForLanguageWithName:[method languageName]];
|
||||
|
||||
/* Get arguments as array */
|
||||
count = [[invocation methodSignature] numberOfArguments];
|
||||
args = [NSMutableArray array];
|
||||
|
||||
for(index = 2; index < count; index++)
|
||||
{
|
||||
arg = [invocation getArgumentAsObjectAtIndex:index];
|
||||
|
||||
if (arg == nil)
|
||||
{
|
||||
[args addObject:STNil];
|
||||
}
|
||||
else
|
||||
{
|
||||
[args addObject:arg];
|
||||
}
|
||||
}
|
||||
|
||||
retval = [engine executeMethod:method
|
||||
forReceiver:self
|
||||
withArguments:args
|
||||
inEnvironment:environment];
|
||||
|
||||
[invocation setReturnValue:&retval];
|
||||
}
|
||||
- (void)encodeWithCoder:(NSCoder *)coder
|
||||
{
|
||||
// [super encodeWithCoder: coder];
|
||||
|
||||
[coder encodeObject:methodDictionary];
|
||||
[coder encodeObject:ivars];
|
||||
}
|
||||
|
||||
- initWithCoder:(NSCoder *)decoder
|
||||
{
|
||||
self = [super init]; //[super initWithCoder: decoder];
|
||||
|
||||
[decoder decodeValueOfObjCType: @encode(id) at: &methodDictionary];
|
||||
[decoder decodeValueOfObjCType: @encode(id) at: &ivars];
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
@end
|
|
@ -2,6 +2,7 @@
|
|||
ScriptingInfoClass = StepTalkScriptingInfo;
|
||||
|
||||
Classes = (
|
||||
STActor,
|
||||
STEnvironment,
|
||||
STLanguage,
|
||||
STScript,
|
||||
|
|
|
@ -189,7 +189,7 @@ extern int STCparse(void *context);
|
|||
int parsRetval = 0;
|
||||
|
||||
|
||||
NSDebugLLog(@"STCompiler", @"Compile method", aString);
|
||||
NSDebugLLog(@"STCompiler", @"Compile method for receiver %@", [receiverObject className]);
|
||||
|
||||
if(!environment)
|
||||
{
|
||||
|
@ -493,12 +493,12 @@ extern int STCparse(void *context);
|
|||
NS_DURING
|
||||
/* test whether variable is an ivar s*/
|
||||
obj = [receiver valueForKey:varName];
|
||||
NSDebugLLog(@"STCompiler", "New name: receiver variable %@", varName);
|
||||
NSDebugLLog(@"STCompiler", @"New name: receiver variable %@", varName);
|
||||
[receiverVars addObject:varName];
|
||||
NS_HANDLER
|
||||
if([[localException name] isEqualToString:NSUndefinedKeyException])
|
||||
{
|
||||
NSDebugLLog(@"STCompiler", "New name: extern %@", varName);
|
||||
NSDebugLLog(@"STCompiler", @"New name: extern %@", varName);
|
||||
/* receiver has no such variable */
|
||||
[externVars addObject:varName];
|
||||
}
|
||||
|
@ -510,7 +510,7 @@ extern int STCparse(void *context);
|
|||
}
|
||||
else
|
||||
{
|
||||
NSDebugLLog(@"STCompiler", "New name: extern %@ (nil receiver)", varName);
|
||||
NSDebugLLog(@"STCompiler", @"New name: extern %@ (nil receiver)", varName);
|
||||
[externVars addObject:varName];
|
||||
}
|
||||
|
||||
|
|
|
@ -164,7 +164,7 @@ const char *STExecutorCommonOptions =
|
|||
{
|
||||
NSDebugLog(@"Executing script '%@'",file);
|
||||
|
||||
env = [conversation environment];
|
||||
env = [conversation context];
|
||||
[env setObject:args forName:@"Args"];
|
||||
[env setObject:env forName:@"Environment"];
|
||||
|
||||
|
@ -216,7 +216,7 @@ const char *STExecutorCommonOptions =
|
|||
NSString *name;
|
||||
NSArray *objects;
|
||||
|
||||
dict = [[conversation environment] objectDictionary];
|
||||
dict = [[conversation context] objectDictionary];
|
||||
|
||||
objects = [[dict allKeys] sortedArrayUsingSelector:@selector(compare:)];
|
||||
|
||||
|
|
Loading…
Reference in a new issue