Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature pseudo object props #1587

Open
wants to merge 9 commits into
base: develop
from
@@ -517,6 +517,10 @@
72D6032A18476FC90022379C /* libicuuc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 721CAAC718351E7400858545 /* libicuuc.a */; };
72DDBF7A19EC011300361E88 /* native-layer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 72DDBF7919EC011300361E88 /* native-layer.cpp */; };
7635171E182A8D3D00C31FA2 /* image_rep_densitymapped.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7635171B182A8D1F00C31FA2 /* image_rep_densitymapped.cpp */; };
7637AC20192DFD2F008FF003 /* exec-files-file.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7637AC1C192DFD2D008FF003 /* exec-files-file.cpp */; };
7637AC21192DFD2F008FF003 /* exec-files-process.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7637AC1D192DFD2D008FF003 /* exec-files-process.cpp */; };
7637AC22192DFD2F008FF003 /* exec-interface-screen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7637AC1E192DFD2E008FF003 /* exec-interface-screen.cpp */; };
7637AC23192DFD2F008FF003 /* exec-network-socket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7637AC1F192DFD2E008FF003 /* exec-network-socket.cpp */; };
763FF4E918522CBE00B45FBA /* image_rep_resampled.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 763FF4E718522CB200B45FBA /* image_rep_resampled.cpp */; };
763FF4EA18522CC100B45FBA /* image_rep_resampled.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 763FF4E718522CB200B45FBA /* image_rep_resampled.cpp */; };
76570D51198BBBDF00614ECD /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DDE08E61945F036000E3705 /* AVFoundation.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
@@ -2186,6 +2190,10 @@
72DDBF7819EC000300361E88 /* native-layer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "native-layer.h"; path = "src/native-layer.h"; sourceTree = "<group>"; };
72DDBF7919EC011300361E88 /* native-layer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "native-layer.cpp"; path = "src/native-layer.cpp"; sourceTree = "<group>"; };
7635171B182A8D1F00C31FA2 /* image_rep_densitymapped.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = image_rep_densitymapped.cpp; path = src/image_rep_densitymapped.cpp; sourceTree = "<group>"; };
7637AC1C192DFD2D008FF003 /* exec-files-file.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "exec-files-file.cpp"; path = "src/exec-files-file.cpp"; sourceTree = "<group>"; };
7637AC1D192DFD2D008FF003 /* exec-files-process.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "exec-files-process.cpp"; path = "src/exec-files-process.cpp"; sourceTree = "<group>"; };
7637AC1E192DFD2E008FF003 /* exec-interface-screen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "exec-interface-screen.cpp"; path = "src/exec-interface-screen.cpp"; sourceTree = "<group>"; };
7637AC1F192DFD2E008FF003 /* exec-network-socket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "exec-network-socket.cpp"; path = "src/exec-network-socket.cpp"; sourceTree = "<group>"; };
763FF4E718522CB200B45FBA /* image_rep_resampled.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = image_rep_resampled.cpp; path = src/image_rep_resampled.cpp; sourceTree = "<group>"; };
766E3292180EE4E000CF7FCF /* graphics_util.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = graphics_util.h; path = src/graphics_util.h; sourceTree = "<group>"; };
766E3293180EE4E000CF7FCF /* graphicscontext.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = graphicscontext.cpp; path = src/graphicscontext.cpp; sourceTree = "<group>"; };
@@ -3336,6 +3344,10 @@
4DE3B0EE15888AA1008EB6B5 /* Exec */ = {
isa = PBXGroup;
children = (
7637AC1C192DFD2D008FF003 /* exec-files-file.cpp */,
7637AC1D192DFD2D008FF003 /* exec-files-process.cpp */,
7637AC1E192DFD2E008FF003 /* exec-interface-screen.cpp */,
7637AC1F192DFD2E008FF003 /* exec-network-socket.cpp */,
4DD9D74E1A3AE4580006366D /* exec-extension.cpp */,
76FA930917FC72FB003DB770 /* exec-strings-chunk.cpp */,
768D665F1762076000F203A3 /* exec-ad.cpp */,
@@ -5283,6 +5295,10 @@
4CF4B883199E0D9900E33AEE /* coretextlayout.mm in Sources */,
E82206E1184F810A00117D10 /* resolution.cpp in Sources */,
72C28AFA1911300D007F2AA0 /* segment.cpp in Sources */,
7637AC20192DFD2F008FF003 /* exec-files-file.cpp in Sources */,
7637AC21192DFD2F008FF003 /* exec-files-process.cpp in Sources */,
7637AC22192DFD2F008FF003 /* exec-interface-screen.cpp in Sources */,
7637AC23192DFD2F008FF003 /* exec-network-socket.cpp in Sources */,
BEBC51DA195350C300215C85 /* coretextfonts.cpp in Sources */,
BEBC51DB195350C300215C85 /* mac-abort.mm in Sources */,
BEBC51DC195350C300215C85 /* mac-color.mm in Sources */,
@@ -53,6 +53,8 @@ along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
#include "syntax.h"
#include "exec.h"

#include "socket.h"

////////////////////////////////////////////////////////////////////////////////

#ifdef COLLECTING_CHUNKS
@@ -140,7 +142,8 @@ MCChunk::MCChunk(Boolean isforset)
function = F_UNDEFINED;
marked = False;
next = NULL;

pseudoobject = NULL;

// MW-2014-05-28: [[ Bug 11928 ]] We assume (at first) we are not a transient text chunk (i.e. one that is evaluated from a var).
m_transient_text_chunk = false;
}
@@ -181,6 +184,8 @@ MCChunk::~MCChunk()
delete trueword;
delete source;
delete destvar;

delete pseudoobject;
}

Parse_stat MCChunk::parse(MCScriptPoint &sp, Boolean doingthe)
@@ -201,59 +206,64 @@ Parse_stat MCChunk::parse(MCScriptPoint &sp, Boolean doingthe)
while (True)
{
if (sp.next(type) != PS_NORMAL)
{
{
if (need_target)
{
MCperror->add(PE_CHUNK_NOCHUNK, sp);
return PS_ERROR;
}
else
break;
}
}
if (type == ST_ID)
{
te = NULL;
if (sp.lookup(SP_FACTOR, te) != PS_NORMAL || te->type == TT_PROPERTY)
{
if (need_target)
{
if (desttype == DT_ISDEST && stack == NULL && background == NULL
&& card == NULL && group == NULL && object == NULL)
{
MCExpression *newfact = NULL;
// MW-2011-06-22: [[ SERVER ]] Update to use SP findvar method to take into account
// execution outwith a handler.
if (doingthe
|| (sp.findvar(sp.gettoken_nameref(), &destvar) != PS_NORMAL
// AL-2014-05-23: [[ PseudoObjectProps ]] Since screen is a property name,
// we have to jump through a few hoops to parse it as a pseudo-object.
if (te == NULL || te->which != P_SCREEN || doingthe)
{
if (need_target)
{
if (desttype == DT_ISDEST && stack == NULL && background == NULL
&& card == NULL && group == NULL && object == NULL && pseudoobject == NULL)
{
MCExpression *newfact = NULL;
// MW-2011-06-22: [[ SERVER ]] Update to use SP findvar method to take into account
// execution outwith a handler.
if (doingthe
|| (sp.findvar(sp.gettoken_nameref(), &destvar) != PS_NORMAL
&& (MCexplicitvariables
|| sp.lookupconstant(&newfact) == PS_NORMAL
|| sp.findnewvar(sp.gettoken_nameref(), kMCEmptyName, &destvar) != PS_NORMAL)))
{
delete newfact;
MCperror->add(PE_CHUNK_NOVARIABLE, sp);
return PS_ERROR;
}
destvar->parsearray(sp);
desttype = DT_VARIABLE;
return PS_NORMAL;
}
else
{
if (doingthe)
sp.backup();
sp.backup();
if (sp.parseexp(True, False, &source) != PS_NORMAL)
{
MCperror->add
(PE_CHUNK_BADEXP, sp);
return PS_ERROR;
}
desttype = DT_EXPRESSION;
}
}
else
sp.backup();
break;
{
delete newfact;
MCperror->add(PE_CHUNK_NOVARIABLE, sp);
return PS_ERROR;
}
destvar->parsearray(sp);
desttype = DT_VARIABLE;
return PS_NORMAL;
}
else
{
if (doingthe)
sp.backup();
sp.backup();
if (sp.parseexp(True, False, &source) != PS_NORMAL)
{
MCperror->add
(PE_CHUNK_BADEXP, sp);
return PS_ERROR;
}
desttype = DT_EXPRESSION;
}
}
else
sp.backup();
break;
}
}
switch (te->type)
{
@@ -332,8 +342,18 @@ Parse_stat MCChunk::parse(MCScriptPoint &sp, Boolean doingthe)
}
marked = True;
break;
case TT_PROPERTY:
case TT_CHUNK:
nterm = (Chunk_term)te->which;
// AL-2014-05-23: [[ PseudoObjectProps ]] Since screen is a property name,
// we have to jump through a few hoops to parse it as a pseudo-object.
if (te->type == TT_PROPERTY)
{
if (te -> which != P_SCREEN)
break;
nterm = CT_SCREEN;
}
else
nterm = (Chunk_term)te->which;
// MW-2013-08-05: [[ ThisMe ]] If 'this' is followed by 'me' we become 'this me'.
if (nterm == CT_THIS &&
sp . skip_token(SP_FACTOR, TT_FUNCTION, F_ME) == PS_NORMAL)
@@ -410,6 +430,14 @@ Parse_stat MCChunk::parse(MCScriptPoint &sp, Boolean doingthe)
case CT_PULLDOWN:
case CT_POPUP:
case CT_OPTION:

// pseudo-object parsing
case CT_SOCKET:
case CT_FILE:
case CT_PROCESS:
case CT_SCREEN:
pseudoobject = curref;
break;
case CT_STACK:
if (oterm > CT_STACK)
{
@@ -4206,9 +4234,69 @@ static MCPropertyInfo *lookup_object_property(const MCObjectPropertyTable *p_tab
return nil;
}

static const MCObjectPropertyTable *get_object_property_table(MCPseudoObjectChunkPtr t_ptr)
{
switch (t_ptr . type)
{
case kMCPseudoObjectTypeSocket:
return MCSocketGetPropertyTable();
case kMCPseudoObjectTypeScreen:
return MCScreenGetPropertyTable();
case kMCPseudoObjectTypeFile:
return MCFileGetPropertyTable();
case kMCPseudoObjectTypeProcess:
return MCProcessGetPropertyTable();
default:
return nil;
}
}

bool MCChunk::setpseudoprop(MCExecContext& ctxt, Properties which, MCNameRef index, Boolean effective, MCExecValue p_value)
{
MCPseudoObjectChunkPtr t_ptr;
if (evalpseudoobject(ctxt, t_ptr) != ES_NORMAL)
return false;

MCPropertyInfo *t_info;
const MCObjectPropertyTable *t_table;
t_table = get_object_property_table(t_ptr);
if (t_table == nil)
return false;

t_info = lookup_object_property(t_table, which, false, false, kMCPropertyInfoChunkTypeNone);

if (t_info == nil)
return false;

MCExecStoreProperty(ctxt, t_info, &t_ptr, p_value);
}

bool MCChunk::getpseudoprop(MCExecContext& ctxt, Properties which, MCNameRef index, Boolean effective, MCExecValue& r_value)
{
MCPseudoObjectChunkPtr t_ptr;
if (evalpseudoobject(ctxt, t_ptr) != ES_NORMAL)
return false;

MCPropertyInfo *t_info;
const MCObjectPropertyTable *t_table;
t_table = get_object_property_table(t_ptr);
if (t_table == nil)
return false;

t_info = lookup_object_property(t_table, which, false, false, kMCPropertyInfoChunkTypeNone);

if (t_info == nil)
return false;

MCExecFetchProperty(ctxt, t_info, &t_ptr, r_value);
}

// MW-2011-11-23: [[ Array Chunk Props ]] If index is not nil, then treat as an array chunk prop
bool MCChunk::getprop(MCExecContext& ctxt, Properties which, MCNameRef index, Boolean effective, MCExecValue& r_value)
{
if (pseudoobject != nil)
return getpseudoprop(ctxt, which, index, effective, r_value);

MCObjectChunkPtr t_obj_chunk;
if (evalobjectchunk(ctxt, false, false, t_obj_chunk) != ES_NORMAL)
return false;
@@ -4271,6 +4359,9 @@ bool MCChunk::getprop(MCExecContext& ctxt, Properties which, MCNameRef index, Bo
// MW-2011-11-23: [[ Array Chunk Props ]] If index is not nil, then treat as an array chunk prop
bool MCChunk::setprop(MCExecContext& ctxt, Properties which, MCNameRef index, Boolean effective, MCExecValue p_value)
{
if (pseudoobject != nil)
return setpseudoprop(ctxt, which, index, effective, p_value);

MCObjectChunkPtr t_obj_chunk;
if (evalobjectchunk(ctxt, false, true, t_obj_chunk) != ES_NORMAL)
return false;
@@ -4476,6 +4567,49 @@ bool MCChunk::evalobjectchunk(MCExecContext &ctxt, bool p_whole_chunk, bool p_fo
return true;
}

bool MCChunk::evalpseudoobject(MCExecContext &ctxt, MCPseudoObjectChunkPtr &r_chunk)
{
if (pseudoobject -> etype != CT_EXPRESSION)
return false;

MCNewAutoNameRef t_exp;
if (!ctxt . EvalExprAsNameRef(pseudoobject -> startpos, EE_CHUNK_CANTFINDOBJECT, &t_exp))
return false;

switch (pseudoobject -> otype)
{
case CT_SOCKET:
if (!MCSocketGetObject(ctxt, *t_exp, r_chunk))
return false;
break;
case CT_PROCESS:
if (!MCProcessGetObject(ctxt, *t_exp, r_chunk))
return false;
break;
case CT_FILE:
if (!MCFileGetObject(ctxt, *t_exp, r_chunk))
return false;
break;
case CT_SCREEN:
if (!MCScreenGetObject(ctxt, *t_exp, r_chunk))
return false;
break;
default:
return false;
}

MCMarkedText t_mark;
t_mark . finish = INDEX_MAX;
t_mark . start = 0;
t_mark . changed = false;
t_mark . text = nil;

r_chunk . chunk = CT_UNDEFINED;
r_chunk . mark = t_mark;

return true;
}

#ifdef LEGACY_EXEC
Exec_stat MCChunk::select(MCExecPoint &ep, Preposition_type where, Boolean text, Boolean first)
{
@@ -55,6 +55,9 @@ class MCChunk : public MCExpression
MCCRef *sentence;
MCCRef *trueword;

// AL [[ Pseudo-objectProperties ]]
MCCRef *pseudoobject;

// MW-2008-03-05: [[ Owner Reference ]] If desttype == DT_OWNER, then this pointer will
// be an MCChunk, otherwise it will be an MCExpression.
MCExpression *source;
@@ -92,6 +95,7 @@ class MCChunk : public MCExpression

bool evalobjectchunk(MCExecContext& ctxt, bool p_whole_chunk, bool p_force, MCObjectChunkPtr& r_chunk);
bool evalvarchunk(MCExecContext& ctxt, bool whole_chunk, bool force, MCVariableChunkPtr& r_chunk);
bool evalpseudoobject(MCExecContext &ctxt, MCPseudoObjectChunkPtr &t_obj);
bool evalurlchunk(MCExecContext& ctxt, bool p_whole_chunk, bool p_force, int p_preposition, MCUrlChunkPtr& r_chunk);

void take_components(MCChunk *tchunk);
@@ -172,6 +176,9 @@ class MCChunk : public MCExpression
bool getprop(MCExecContext& ctxt, Properties which, MCNameRef index, Boolean effective, MCExecValue& r_value);
bool setprop(MCExecContext& ctxt, Properties which, MCNameRef index, Boolean effective, MCExecValue p_value);

bool setpseudoprop(MCExecContext& ctxt, Properties which, MCNameRef index, Boolean effective, MCExecValue p_value);
bool getpseudoprop(MCExecContext& ctxt, Properties which, MCNameRef index, Boolean effective, MCExecValue& r_value);

#ifdef LEGACY_EXEC
Exec_stat getprop_legacy(Properties w, MCExecPoint &, MCNameRef index, Boolean effective);
Exec_stat setprop_legacy(Properties w, MCExecPoint &, MCNameRef index, Boolean effective);
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.