Evaluation works!

This commit is contained in:
2022-06-13 15:10:12 +02:00
parent 004db89c60
commit 81a483d540
28 changed files with 307 additions and 198 deletions

View File

@@ -22,7 +22,7 @@ CarpApplication >> baseApplication [
CarpApplication >> debuggerClientFor: anException [
"Answer the debugger client to be used by the Gt Post Mortem debugger"
^ GtPythonPostMortemDebugger new exception: anException
^ CarpPostMortemDebugger new exception: anException
]
{ #category : #accessing }

View File

@@ -0,0 +1,10 @@
Class {
#name : #CarpCommand,
#superclass : #LanguageLinkCommand,
#category : #'Carp-LanguageLink'
}
{ #category : #accessing }
CarpCommand >> codeForRemote [
^ (Character space join: self instructions) copyReplaceAll: Character cr asString with: Character lf asString
]

View File

@@ -3,3 +3,13 @@ Class {
#superclass : #LanguageLinkCommandFactory,
#category : #'Carp-Execution'
}
{ #category : #accessing }
CarpCommandFactory >> command [
^ command
]
{ #category : #accessing }
CarpCommandFactory >> instructionsWithNotifyAtEnd [
^ instructions
]

View File

@@ -4,19 +4,19 @@ Class {
#category : #'Carp-Serialization'
}
{ #category : #'instance creation' }
CarpDeserializer class >> deserialize: anObject [
^ self new
deserialize: anObject
]
{ #category : #accessing }
CarpDeserializer >> buildProxyFor: rawObject [
| proxy |
proxy := CarpProxyObject
carpType: (rawObject at: #carptype)
var: (rawObject at: #carpvar) asJSGI
var: (rawObject at: #carpvar)
application: self application.
self executionHandler registerObject: proxy.
^ proxy
]
{ #category : #accessing }
CarpDeserializer >> deserialize: anObject [
^ self new
deserialize: anObject
]

View File

@@ -23,7 +23,7 @@ CarpPostMortemDebugger >> exception: anException [
CarpPostMortemDebugger >> initialize [
super initialize.
frameRegex := '\s+at.+\(([^:]+)\:(\d+)\:(\d+)\)' asRegexIgnoringCase.
frameRegex := '(.*)\s+at.+([^:]+)\:(\d+)\:(\d+)\.' asRegexIgnoringCase.
]
{ #category : #accessing }
@@ -37,16 +37,19 @@ CarpPostMortemDebugger >> sourceStyler [
CarpPostMortemDebugger >> stackFrameFromLine: aString ordinal: ordinal [
"Answer a frame if the supplied string contains a valid file and line number, or nil"
<return: #GtPythonPostMortemStackFrame or: nil>
| file line column |
| file line column source |
^ (frameRegex search: aString) ifTrue:
[ file := frameRegex subexpression: 2.
line := frameRegex subexpression: 3.
column := frameRegex subexpression: 4.
file := frameRegex subexpression: 3.
line := frameRegex subexpression: 4.
column := frameRegex subexpression: 5.
self halt.
CarpPostMortemStackFrame new
ordinal: ordinal;
displayString: aString;
exception: exception;
source: source;
file: file asFileReference;
line: line asNumber;
column: column asNumber ]

View File

@@ -1,5 +1,18 @@
Class {
#name : #CarpPostMortemStackFrame,
#superclass : #GtJavaScriptPostMortemStackFrame,
#instVars : [
'source'
],
#category : #'Carp-Debugger'
}
{ #category : #accessing }
CarpPostMortemStackFrame >> source: aString [
source := aString
]
{ #category : #accessing }
CarpPostMortemStackFrame >> sourceText [
^ source
]

View File

@@ -3,7 +3,8 @@ Class {
#superclass : #GtSourceCoder,
#instVars : [
'pharoBindings',
'carpLinkApplicationStrategy'
'carpLinkApplicationStrategy',
'exception'
],
#category : #'Carp-Coder'
}
@@ -24,35 +25,37 @@ GtCarpCoderModel >> asCoderViewModel [
{ #category : #accessing }
GtCarpCoderModel >> bindAndExecute: sourceString [
"Answer the source code with all declared variables returned in an immediate dictionary"
<gtIgnoreConstraint: #GtRBAcceptVisitorCalledFromNonVisitingMethods>
| carpSource trimmedSource ast varNames lastStatement application commandFactory |
<remoteDebuggerSignal>
| carpSource trimmedSource ast varNames lastStatement application commandFactory res |
trimmedSource := SmaCCString on: sourceString trimRight.
ast := CarpParser parse: trimmedSource.
"The variables to be returned are names that are in pharoBindings"
varNames := pharoBindings bindingNames asSet.
"Assign the final statement to snippetResult"
ast := CarpParser parse: trimmedSource. "The variables to be returned are names that are in pharoBindings"
varNames := pharoBindings bindingNames asSet. "Assign the final statement to snippetResult"
lastStatement := ast expressions last.
trimmedSource
insert: '(defdynamic snippetResult '
trimmedSource
insert: '(defdynamic snippetResult '
at: lastStatement startPosition.
trimmedSource
insert: ')'
at: lastStatement stopPosition.
varNames add: 'snippetResult'.
"Get the final source to execute"
carpSource := self sourceFrom: trimmedSource asString returnedVarNames: varNames.
trimmedSource insert: ')' at: lastStatement stopPosition.
varNames add: 'snippetResult'. "Get the final source to execute"
carpSource := self
sourceFrom: trimmedSource asString
returnedVarNames: varNames.
application := carpLinkApplicationStrategy applicationServer.
application isRunning ifFalse: [ application start ].
commandFactory := application newCommandFactory.
^ commandFactory
<< carpSource;
sendAndWait.
res := commandFactory
<< carpSource;
sendAndWait.
(res at: #result) = 'success' ifTrue: [ ^ res at: #value ].
exception := (PharoLinkRemoteError new
application: application;
command: commandFactory command;
trace: (res at: #value)).
exception signal
]
{ #category : #accessing }
@@ -66,6 +69,11 @@ GtCarpCoderModel >> computeAst: theSourceString [
parseWithErrors: theSourceString
]
{ #category : #accessing }
GtCarpCoderModel >> exception [
^ exception
]
{ #category : #accessing }
GtCarpCoderModel >> initializeAddOns: addOns [
super initializeAddOns: addOns.
@@ -113,36 +121,17 @@ GtCarpCoderModel >> pharoBindings: anObject [
{ #category : #accessing }
GtCarpCoderModel >> primitiveEvaluate: aSourceString inContext: aGtSourceCoderEvaluationContext onFailDo: anEvaluationFailBlock [
| result |
result := self bindAndExecute: aSourceString.
result associationsDo: [ :binding |
(pharoBindings bindingOf: binding key asSymbol) value: binding value ].
^ result
at: 'snippetResult'
ifAbsent: anEvaluationFailBlock
^ (CarpParser parse: (self bindAndExecute: aSourceString)) expressions first toPharo
]
{ #category : #accessing }
GtCarpCoderModel >> sourceFrom: trimmedSourceString returnedVarNames: varNames [
"Answer the modified source to return the declared variables"
^ String streamContents: [ :stream |
stream << trimmedSourceString.
stream
cr
<< '{ '.
varNames do: [ :varName |
stream
<< '(quote ';
<< varName;
<< ') ';
<< varName;
<< ' ' ].
"Answer the variable dictionary as an immediate object"
stream
<< '(quote carpLinkImmediate) true }' ]
^ String
streamContents: [ :stream |
stream << trimmedSourceString.
stream lf << 'snippetResult' ]
]
{ #category : #accessing }

View File

@@ -12,7 +12,7 @@ LanguageLinkSettings class >> carpDefaultSettings [
serverProcessClass: CarpPythonProcess;
platform: CarpPlatform new;
commandFactoryClass: CarpCommandFactory;
commandClass: LanguageLinkCommand;
commandClass: CarpCommand;
serializerClass: LanguageLinkSerializer;
deserializerClass: CarpDeserializer;
parserClass: CarpParser;

View File

@@ -41,15 +41,16 @@ LeCarpApplicationStrategy >> newCarpApplicationFor: aLeDatabase [
{ #category : #accessing }
LeCarpApplicationStrategy >> updatedSettings: applicationCarpSettings [
"Update the supplied settings with the lepiter configuration"
| lepiterCarpSettings lepiterDatabase carpDir |
| lepiterCarpSettings lepiterDatabase carpDir |
lepiterDatabase := content database.
(lepiterDatabase isKindOf: LeNullDatabase)
ifTrue: [ ^ applicationCarpSettings ].
lepiterCarpSettings := lepiterDatabase properties carpLinkSettings.
lepiterCarpSettings directory ifNotNil:
[ :relativeDir |
lepiterCarpSettings directory
ifNotNil: [ :relativeDir |
carpDir := lepiterDatabase localStoreRootDirectory resolve: relativeDir.
applicationCarpSettings workingDirectory: carpDir ].
"lepiterCarpSettings carpPath ifNotNil:
applicationCarpSettings workingDirectory: carpDir ]. "lepiterCarpSettings carpPath ifNotNil:
[ :carpPath | applicationCarpSettings serverExecutable: carpPath ]."
applicationCarpSettings serverDebugMode: lepiterCarpSettings serverDebugMode.