mirror of
https://github.com/gnustep/libs-steptalk.git
synced 2025-02-19 09:50:43 +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
|
* STEnvironment: search class name namespace when no object is found for
|
||||||
given name and full scripting is enabled.
|
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 = \
|
StepTalk_OBJC_FILES = \
|
||||||
NSInvocation+additions.m \
|
NSInvocation+additions.m \
|
||||||
|
STActor.m \
|
||||||
STBehaviourInfo.m \
|
STBehaviourInfo.m \
|
||||||
STBundleInfo.m \
|
STBundleInfo.m \
|
||||||
STClassInfo.m \
|
STClassInfo.m \
|
||||||
|
@ -58,6 +59,7 @@ StepTalk_OBJC_FILES = \
|
||||||
# STDistantEnvironment.m \
|
# STDistantEnvironment.m \
|
||||||
|
|
||||||
STEPTALK_HEADER_FILES = \
|
STEPTALK_HEADER_FILES = \
|
||||||
|
STActor.h \
|
||||||
STBundleInfo.h \
|
STBundleInfo.h \
|
||||||
STContext.h \
|
STContext.h \
|
||||||
STConversation.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;
|
ScriptingInfoClass = StepTalkScriptingInfo;
|
||||||
|
|
||||||
Classes = (
|
Classes = (
|
||||||
|
STActor,
|
||||||
STEnvironment,
|
STEnvironment,
|
||||||
STLanguage,
|
STLanguage,
|
||||||
STScript,
|
STScript,
|
||||||
|
|
|
@ -189,7 +189,7 @@ extern int STCparse(void *context);
|
||||||
int parsRetval = 0;
|
int parsRetval = 0;
|
||||||
|
|
||||||
|
|
||||||
NSDebugLLog(@"STCompiler", @"Compile method", aString);
|
NSDebugLLog(@"STCompiler", @"Compile method for receiver %@", [receiverObject className]);
|
||||||
|
|
||||||
if(!environment)
|
if(!environment)
|
||||||
{
|
{
|
||||||
|
@ -493,12 +493,12 @@ extern int STCparse(void *context);
|
||||||
NS_DURING
|
NS_DURING
|
||||||
/* test whether variable is an ivar s*/
|
/* test whether variable is an ivar s*/
|
||||||
obj = [receiver valueForKey:varName];
|
obj = [receiver valueForKey:varName];
|
||||||
NSDebugLLog(@"STCompiler", "New name: receiver variable %@", varName);
|
NSDebugLLog(@"STCompiler", @"New name: receiver variable %@", varName);
|
||||||
[receiverVars addObject:varName];
|
[receiverVars addObject:varName];
|
||||||
NS_HANDLER
|
NS_HANDLER
|
||||||
if([[localException name] isEqualToString:NSUndefinedKeyException])
|
if([[localException name] isEqualToString:NSUndefinedKeyException])
|
||||||
{
|
{
|
||||||
NSDebugLLog(@"STCompiler", "New name: extern %@", varName);
|
NSDebugLLog(@"STCompiler", @"New name: extern %@", varName);
|
||||||
/* receiver has no such variable */
|
/* receiver has no such variable */
|
||||||
[externVars addObject:varName];
|
[externVars addObject:varName];
|
||||||
}
|
}
|
||||||
|
@ -510,7 +510,7 @@ extern int STCparse(void *context);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NSDebugLLog(@"STCompiler", "New name: extern %@ (nil receiver)", varName);
|
NSDebugLLog(@"STCompiler", @"New name: extern %@ (nil receiver)", varName);
|
||||||
[externVars addObject:varName];
|
[externVars addObject:varName];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -164,7 +164,7 @@ const char *STExecutorCommonOptions =
|
||||||
{
|
{
|
||||||
NSDebugLog(@"Executing script '%@'",file);
|
NSDebugLog(@"Executing script '%@'",file);
|
||||||
|
|
||||||
env = [conversation environment];
|
env = [conversation context];
|
||||||
[env setObject:args forName:@"Args"];
|
[env setObject:args forName:@"Args"];
|
||||||
[env setObject:env forName:@"Environment"];
|
[env setObject:env forName:@"Environment"];
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ const char *STExecutorCommonOptions =
|
||||||
NSString *name;
|
NSString *name;
|
||||||
NSArray *objects;
|
NSArray *objects;
|
||||||
|
|
||||||
dict = [[conversation environment] objectDictionary];
|
dict = [[conversation context] objectDictionary];
|
||||||
|
|
||||||
objects = [[dict allKeys] sortedArrayUsingSelector:@selector(compare:)];
|
objects = [[dict allKeys] sortedArrayUsingSelector:@selector(compare:)];
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue