mirror of
https://github.com/google/blockly.git
synced 2026-01-07 00:50:27 +01:00
still working on tests, lists are the only unfinished
This commit is contained in:
@@ -32,8 +32,10 @@ goog.provide('Blockly.Names');
|
||||
* @param {string} reservedWords A comma-separated string of words that are
|
||||
* illegal for use as names in a language (e.g. 'new,if,this,...').
|
||||
* @constructor
|
||||
* @param namesPrependDollar boolean indicating whether the languages requires dollar signs ($) before a variable
|
||||
*/
|
||||
Blockly.Names = function(reservedWords) {
|
||||
Blockly.Names = function(reservedWords, namesPrependDollar) {
|
||||
this.prependDollar = namesPrependDollar || false;
|
||||
this.reservedDict_ = Object.create(null);
|
||||
if (reservedWords) {
|
||||
var splitWords = reservedWords.split(',');
|
||||
@@ -70,11 +72,12 @@ Blockly.Names.prototype.reset = function() {
|
||||
*/
|
||||
Blockly.Names.prototype.getName = function(name, type) {
|
||||
var normalized = name.toLowerCase() + '_' + type;
|
||||
var prepend = type=='VARIABLE' && this.prependDollar ? '$' : '';
|
||||
if (normalized in this.db_) {
|
||||
return this.db_[normalized];
|
||||
return prepend + this.db_[normalized];
|
||||
}
|
||||
var safeName = this.getDistinctName(name, type);
|
||||
this.db_[normalized] = safeName;
|
||||
this.db_[normalized] = type=='VARIABLE' && this.prependDollar ? safeName.substr(1) : safeName;
|
||||
return safeName;
|
||||
};
|
||||
|
||||
@@ -98,7 +101,8 @@ Blockly.Names.prototype.getDistinctName = function(name, type) {
|
||||
}
|
||||
safeName += i;
|
||||
this.dbReverse_[safeName] = true;
|
||||
return safeName;
|
||||
var prepend = type=='VARIABLE' && this.prependDollar ? '$' : '';
|
||||
return prepend + safeName;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @license
|
||||
* Visual Blocks Language
|
||||
*
|
||||
* Copyright 2015 Google Inc.
|
||||
* Copyright 2012 Google Inc.
|
||||
* https://developers.google.com/blockly/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
/**
|
||||
* @fileoverview Helper functions for generating PHP for blocks.
|
||||
* @author daarond@gmail.com (Daaron Dwyer)
|
||||
* @author fraser@google.com (Neil Fraser)
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
@@ -43,19 +43,36 @@ Blockly.PHP = new Blockly.Generator('PHP');
|
||||
* @private
|
||||
*/
|
||||
Blockly.PHP.addReservedWords(
|
||||
// http://php.net/manual/en/reserved.keywords.php
|
||||
'__halt_compiler,abstract,and,array,as,break,callable,case,catch,class,clone,const,continue,declare,default,die,do,echo,else,elseif,empty,enddeclare,endfor,endforeach,endif,endswitch,endwhile,eval,exit,extends,final,for,foreach,function,global,goto,if,implements,include,include_once,instanceof,insteadof,interface,isset,list,namespace,new,or,print,private,protected,public,require,require_once,return,static,switch,throw,trait,try,unset,use,var,while,xor,' +
|
||||
// http://php.net/manual/en/reserved.constants.php
|
||||
'PHP_VERSION,PHP_MAJOR_VERSION,PHP_MINOR_VERSION,PHP_RELEASE_VERSION,PHP_VERSION_ID,PHP_EXTRA_VERSION,PHP_ZTS,PHP_DEBUG,PHP_MAXPATHLEN,PHP_OS,PHP_SAPI,PHP_EOL,PHP_INT_MAX,PHP_INT_SIZE,DEFAULT_INCLUDE_PATH,PEAR_INSTALL_DIR,PEAR_EXTENSION_DIR,PHP_EXTENSION_DIR,PHP_PREFIX,PHP_BINDIR,PHP_BINARY,PHP_MANDIR,PHP_LIBDIR,PHP_DATADIR,PHP_SYSCONFDIR,PHP_LOCALSTATEDIR,PHP_CONFIG_FILE_PATH,PHP_CONFIG_FILE_SCAN_DIR,PHP_SHLIB_SUFFIX,E_ERROR,E_WARNING,E_PARSE,E_NOTICE,E_CORE_ERROR,E_CORE_WARNING,E_COMPILE_ERROR,E_COMPILE_WARNING,E_USER_ERROR,E_USER_WARNING,E_USER_NOTICE,E_DEPRECATED,E_USER_DEPRECATED,E_ALL,E_STRICT,__COMPILER_HALT_OFFSET__,TRUE,FALSE,NULL,__CLASS__,__DIR__,__FILE__,__FUNCTION__,__LINE__,__METHOD__,__NAMESPACE__,__TRAIT__');
|
||||
'Blockly,' + // In case JS is evaled in the current window.
|
||||
// https://developer.mozilla.org/en/PHP/Reference/Reserved_Words
|
||||
'break,case,catch,continue,debugger,default,delete,do,else,finally,for,function,if,in,instanceof,new,return,switch,this,throw,try,typeof,var,void,while,with,' +
|
||||
'class,enum,export,extends,import,super,implements,interface,let,package,private,protected,public,static,yield,' +
|
||||
'const,null,true,false,' +
|
||||
// https://developer.mozilla.org/en/PHP/Reference/Global_Objects
|
||||
'Array,ArrayBuffer,Boolean,Date,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,Error,eval,EvalError,Float32Array,Float64Array,Function,Infinity,Int16Array,Int32Array,Int8Array,isFinite,isNaN,Iterator,JSON,Math,NaN,Number,Object,parseFloat,parseInt,RangeError,ReferenceError,RegExp,StopIteration,String,SyntaxError,TypeError,Uint16Array,Uint32Array,Uint8Array,Uint8ClampedArray,undefined,uneval,URIError,' +
|
||||
// https://developer.mozilla.org/en/DOM/window
|
||||
'applicationCache,closed,Components,content,_content,controllers,crypto,defaultStatus,dialogArguments,directories,document,frameElement,frames,fullScreen,globalStorage,history,innerHeight,innerWidth,length,location,locationbar,localStorage,menubar,messageManager,mozAnimationStartTime,mozInnerScreenX,mozInnerScreenY,mozPaintCount,name,navigator,opener,outerHeight,outerWidth,pageXOffset,pageYOffset,parent,performance,personalbar,pkcs11,returnValue,screen,screenX,screenY,scrollbars,scrollMaxX,scrollMaxY,scrollX,scrollY,self,sessionStorage,sidebar,status,statusbar,toolbar,top,URL,window,' +
|
||||
'addEventListener,alert,atob,back,blur,btoa,captureEvents,clearImmediate,clearInterval,clearTimeout,close,confirm,disableExternalCapture,dispatchEvent,dump,enableExternalCapture,escape,find,focus,forward,GeckoActiveXObject,getAttention,getAttentionWithCycleCount,getComputedStyle,getSelection,home,matchMedia,maximize,minimize,moveBy,moveTo,mozRequestAnimationFrame,open,openDialog,postMessage,print,prompt,QueryInterface,releaseEvents,removeEventListener,resizeBy,resizeTo,restore,routeEvent,scroll,scrollBy,scrollByLines,scrollByPages,scrollTo,setCursor,setImmediate,setInterval,setResizable,setTimeout,showModalDialog,sizeToContent,stop,unescape,updateCommands,XPCNativeWrapper,XPCSafeJSObjectWrapper,' +
|
||||
'onabort,onbeforeunload,onblur,onchange,onclick,onclose,oncontextmenu,ondevicemotion,ondeviceorientation,ondragdrop,onerror,onfocus,onhashchange,onkeydown,onkeypress,onkeyup,onload,onmousedown,onmousemove,onmouseout,onmouseover,onmouseup,onmozbeforepaint,onpaint,onpopstate,onreset,onresize,onscroll,onselect,onsubmit,onunload,onpageshow,onpagehide,' +
|
||||
'Image,Option,Worker,' +
|
||||
// https://developer.mozilla.org/en/Gecko_DOM_Reference
|
||||
'Event,Range,File,FileReader,Blob,BlobBuilder,' +
|
||||
'Attr,CDATASection,CharacterData,Comment,console,DocumentFragment,DocumentType,DomConfiguration,DOMError,DOMErrorHandler,DOMException,DOMImplementation,DOMImplementationList,DOMImplementationRegistry,DOMImplementationSource,DOMLocator,DOMObject,DOMString,DOMStringList,DOMTimeStamp,DOMUserData,Entity,EntityReference,MediaQueryList,MediaQueryListListener,NameList,NamedNodeMap,Node,NodeFilter,NodeIterator,NodeList,Notation,Plugin,PluginArray,ProcessingInstruction,SharedWorker,Text,TimeRanges,Treewalker,TypeInfo,UserDataHandler,Worker,WorkerGlobalScope,' +
|
||||
'HTMLDocument,HTMLElement,HTMLAnchorElement,HTMLAppletElement,HTMLAudioElement,HTMLAreaElement,HTMLBaseElement,HTMLBaseFontElement,HTMLBodyElement,HTMLBRElement,HTMLButtonElement,HTMLCanvasElement,HTMLDirectoryElement,HTMLDivElement,HTMLDListElement,HTMLEmbedElement,HTMLFieldSetElement,HTMLFontElement,HTMLFormElement,HTMLFrameElement,HTMLFrameSetElement,HTMLHeadElement,HTMLHeadingElement,HTMLHtmlElement,HTMLHRElement,HTMLIFrameElement,HTMLImageElement,HTMLInputElement,HTMLKeygenElement,HTMLLabelElement,HTMLLIElement,HTMLLinkElement,HTMLMapElement,HTMLMenuElement,HTMLMetaElement,HTMLModElement,HTMLObjectElement,HTMLOListElement,HTMLOptGroupElement,HTMLOptionElement,HTMLOutputElement,HTMLParagraphElement,HTMLParamElement,HTMLPreElement,HTMLQuoteElement,HTMLScriptElement,HTMLSelectElement,HTMLSourceElement,HTMLSpanElement,HTMLStyleElement,HTMLTableElement,HTMLTableCaptionElement,HTMLTableCellElement,HTMLTableDataCellElement,HTMLTableHeaderCellElement,HTMLTableColElement,HTMLTableRowElement,HTMLTableSectionElement,HTMLTextAreaElement,HTMLTimeElement,HTMLTitleElement,HTMLTrackElement,HTMLUListElement,HTMLUnknownElement,HTMLVideoElement,' +
|
||||
'HTMLCanvasElement,CanvasRenderingContext2D,CanvasGradient,CanvasPattern,TextMetrics,ImageData,CanvasPixelArray,HTMLAudioElement,HTMLVideoElement,NotifyAudioAvailableEvent,HTMLCollection,HTMLAllCollection,HTMLFormControlsCollection,HTMLOptionsCollection,HTMLPropertiesCollection,DOMTokenList,DOMSettableTokenList,DOMStringMap,RadioNodeList,' +
|
||||
'SVGDocument,SVGElement,SVGAElement,SVGAltGlyphElement,SVGAltGlyphDefElement,SVGAltGlyphItemElement,SVGAnimationElement,SVGAnimateElement,SVGAnimateColorElement,SVGAnimateMotionElement,SVGAnimateTransformElement,SVGSetElement,SVGCircleElement,SVGClipPathElement,SVGColorProfileElement,SVGCursorElement,SVGDefsElement,SVGDescElement,SVGEllipseElement,SVGFilterElement,SVGFilterPrimitiveStandardAttributes,SVGFEBlendElement,SVGFEColorMatrixElement,SVGFEComponentTransferElement,SVGFECompositeElement,SVGFEConvolveMatrixElement,SVGFEDiffuseLightingElement,SVGFEDisplacementMapElement,SVGFEDistantLightElement,SVGFEFloodElement,SVGFEGaussianBlurElement,SVGFEImageElement,SVGFEMergeElement,SVGFEMergeNodeElement,SVGFEMorphologyElement,SVGFEOffsetElement,SVGFEPointLightElement,SVGFESpecularLightingElement,SVGFESpotLightElement,SVGFETileElement,SVGFETurbulenceElement,SVGComponentTransferFunctionElement,SVGFEFuncRElement,SVGFEFuncGElement,SVGFEFuncBElement,SVGFEFuncAElement,SVGFontElement,SVGFontFaceElement,SVGFontFaceFormatElement,SVGFontFaceNameElement,SVGFontFaceSrcElement,SVGFontFaceUriElement,SVGForeignObjectElement,SVGGElement,SVGGlyphElement,SVGGlyphRefElement,SVGGradientElement,SVGLinearGradientElement,SVGRadialGradientElement,SVGHKernElement,SVGImageElement,SVGLineElement,SVGMarkerElement,SVGMaskElement,SVGMetadataElement,SVGMissingGlyphElement,SVGMPathElement,SVGPathElement,SVGPatternElement,SVGPolylineElement,SVGPolygonElement,SVGRectElement,SVGScriptElement,SVGStopElement,SVGStyleElement,SVGSVGElement,SVGSwitchElement,SVGSymbolElement,SVGTextElement,SVGTextPathElement,SVGTitleElement,SVGTRefElement,SVGTSpanElement,SVGUseElement,SVGViewElement,SVGVKernElement,' +
|
||||
'SVGAngle,SVGColor,SVGICCColor,SVGElementInstance,SVGElementInstanceList,SVGLength,SVGLengthList,SVGMatrix,SVGNumber,SVGNumberList,SVGPaint,SVGPoint,SVGPointList,SVGPreserveAspectRatio,SVGRect,SVGStringList,SVGTransform,SVGTransformList,' +
|
||||
'SVGAnimatedAngle,SVGAnimatedBoolean,SVGAnimatedEnumeration,SVGAnimatedInteger,SVGAnimatedLength,SVGAnimatedLengthList,SVGAnimatedNumber,SVGAnimatedNumberList,SVGAnimatedPreserveAspectRatio,SVGAnimatedRect,SVGAnimatedString,SVGAnimatedTransformList,' +
|
||||
'SVGPathSegList,SVGPathSeg,SVGPathSegArcAbs,SVGPathSegArcRel,SVGPathSegClosePath,SVGPathSegCurvetoCubicAbs,SVGPathSegCurvetoCubicRel,SVGPathSegCurvetoCubicSmoothAbs,SVGPathSegCurvetoCubicSmoothRel,SVGPathSegCurvetoQuadraticAbs,SVGPathSegCurvetoQuadraticRel,SVGPathSegCurvetoQuadraticSmoothAbs,SVGPathSegCurvetoQuadraticSmoothRel,SVGPathSegLinetoAbs,SVGPathSegLinetoHorizontalAbs,SVGPathSegLinetoHorizontalRel,SVGPathSegLinetoRel,SVGPathSegLinetoVerticalAbs,SVGPathSegLinetoVerticalRel,SVGPathSegMovetoAbs,SVGPathSegMovetoRel,ElementTimeControl,TimeEvent,SVGAnimatedPathData,' +
|
||||
'SVGAnimatedPoints,SVGColorProfileRule,SVGCSSRule,SVGExternalResourcesRequired,SVGFitToViewBox,SVGLangSpace,SVGLocatable,SVGRenderingIntent,SVGStylable,SVGTests,SVGTextContentElement,SVGTextPositioningElement,SVGTransformable,SVGUnitTypes,SVGURIReference,SVGViewSpec,SVGZoomAndPan');
|
||||
|
||||
/**
|
||||
* Order of operation ENUMs.
|
||||
* http://php.net/manual/en/language.operators.precedence.php
|
||||
* https://developer.mozilla.org/en/PHP/Reference/Operators/Operator_Precedence
|
||||
*/
|
||||
Blockly.PHP.ORDER_ATOMIC = 0; // 0 "" ...
|
||||
Blockly.PHP.ORDER_CLONE = 1; // clone
|
||||
Blockly.PHP.ORDER_MEMBER = 1; // . []
|
||||
Blockly.PHP.ORDER_NEW = 1; // new
|
||||
Blockly.PHP.ORDER_MEMBER = 2; // ()
|
||||
Blockly.PHP.ORDER_FUNCTION_CALL = 2; // ()
|
||||
Blockly.PHP.ORDER_INCREMENT = 3; // ++
|
||||
Blockly.PHP.ORDER_DECREMENT = 3; // --
|
||||
@@ -63,6 +80,9 @@ Blockly.PHP.ORDER_LOGICAL_NOT = 4; // !
|
||||
Blockly.PHP.ORDER_BITWISE_NOT = 4; // ~
|
||||
Blockly.PHP.ORDER_UNARY_PLUS = 4; // +
|
||||
Blockly.PHP.ORDER_UNARY_NEGATION = 4; // -
|
||||
Blockly.PHP.ORDER_TYPEOF = 4; // typeof
|
||||
Blockly.PHP.ORDER_VOID = 4; // void
|
||||
Blockly.PHP.ORDER_DELETE = 4; // delete
|
||||
Blockly.PHP.ORDER_MULTIPLICATION = 5; // *
|
||||
Blockly.PHP.ORDER_DIVISION = 5; // /
|
||||
Blockly.PHP.ORDER_MODULUS = 5; // %
|
||||
@@ -76,10 +96,10 @@ Blockly.PHP.ORDER_EQUALITY = 9; // == != === !==
|
||||
Blockly.PHP.ORDER_BITWISE_AND = 10; // &
|
||||
Blockly.PHP.ORDER_BITWISE_XOR = 11; // ^
|
||||
Blockly.PHP.ORDER_BITWISE_OR = 12; // |
|
||||
Blockly.PHP.ORDER_CONDITIONAL = 13; // ?:
|
||||
Blockly.PHP.ORDER_ASSIGNMENT = 14; // = += -= *= /= %= <<= >>= ...
|
||||
Blockly.PHP.ORDER_LOGICAL_AND = 15; // &&
|
||||
Blockly.PHP.ORDER_LOGICAL_OR = 16; // ||
|
||||
Blockly.PHP.ORDER_LOGICAL_AND = 13; // &&
|
||||
Blockly.PHP.ORDER_LOGICAL_OR = 14; // ||
|
||||
Blockly.PHP.ORDER_CONDITIONAL = 15; // ?:
|
||||
Blockly.PHP.ORDER_ASSIGNMENT = 16; // = += -= *= /= %= <<= >>= ...
|
||||
Blockly.PHP.ORDER_COMMA = 17; // ,
|
||||
Blockly.PHP.ORDER_NONE = 99; // (...)
|
||||
|
||||
@@ -96,36 +116,18 @@ Blockly.PHP.init = function(workspace) {
|
||||
|
||||
if (!Blockly.PHP.variableDB_) {
|
||||
Blockly.PHP.variableDB_ =
|
||||
new Blockly.Names(Blockly.PHP.RESERVED_WORDS_);
|
||||
new Blockly.Names(Blockly.PHP.RESERVED_WORDS_, true);
|
||||
} else {
|
||||
Blockly.PHP.variableDB_.reset();
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.PHP.getDistinctName = function(name, type) {
|
||||
var safeName = this.variableDB_.safeName_(name);
|
||||
var i = '';
|
||||
while ((type == Blockly.Procedures.NAME_TYPE && (safeName + i) in this.variableDB_.reservedDict_)
|
||||
|| this.variableDB_.dbReverse_[safeName + i]) {
|
||||
// Collision with existing name. Create a unique name.
|
||||
i = i ? i + 1 : 2;
|
||||
var defvars = [];
|
||||
var variables = Blockly.Variables.allVariables(workspace);
|
||||
for (var x = 0; x < variables.length; x++) {
|
||||
defvars[x] = Blockly.PHP.variableDB_.getName(variables[x],
|
||||
Blockly.Variables.NAME_TYPE) + ';';
|
||||
}
|
||||
safeName += i;
|
||||
this.variableDB_.dbReverse_[safeName] = true;
|
||||
if (type == Blockly.Variables.NAME_TYPE) {
|
||||
safeName = '$' + safeName;
|
||||
}
|
||||
return safeName;
|
||||
};
|
||||
|
||||
Blockly.PHP.getName = function(name, type) {
|
||||
var normalized = name.toLowerCase() + '_' + type;
|
||||
if (normalized in this.variableDB_.db_) {
|
||||
return this.variableDB_.db_[normalized];
|
||||
}
|
||||
var safeName = this.getDistinctName(name, type);
|
||||
this.variableDB_[normalized] = safeName;
|
||||
return safeName;
|
||||
Blockly.PHP.definitions_['variables'] = defvars.join('\n');
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -68,48 +68,73 @@ Blockly.PHP['lists_repeat'] = function(block) {
|
||||
Blockly.PHP['lists_length'] = function(block) {
|
||||
// List length.
|
||||
var argument0 = Blockly.PHP.valueToCode(block, 'VALUE',
|
||||
Blockly.PHP.ORDER_FUNCTION_CALL) || '[]';
|
||||
Blockly.PHP.ORDER_FUNCTION_CALL) || 'array()';
|
||||
return ['count(' + argument0 + ')', Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
Blockly.PHP['lists_isEmpty'] = function(block) {
|
||||
// Is the list empty?
|
||||
var argument0 = Blockly.PHP.valueToCode(block, 'VALUE',
|
||||
Blockly.PHP.ORDER_FUNCTION_CALL) || '[]';
|
||||
Blockly.PHP.ORDER_FUNCTION_CALL) || 'array()';
|
||||
return ['empty(' + argument0 + ')', Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
Blockly.PHP['lists_indexOf'] = function(block) {
|
||||
// Find an item in the list.
|
||||
var operator = block.getFieldValue('END') == 'FIRST' ?
|
||||
'indexOf' : 'lastIndexOf';
|
||||
var operator = block.getFieldValue('END');
|
||||
var argument0 = Blockly.PHP.valueToCode(block, 'FIND',
|
||||
Blockly.PHP.ORDER_FUNCTION_CALL) || '\'\'';
|
||||
var argument1 = Blockly.PHP.valueToCode(block, 'VALUE',
|
||||
Blockly.PHP.ORDER_FUNCTION_CALL) || '[]';
|
||||
var code = argument1 + '.' + operator + '(' + argument0 + ') + 1';
|
||||
Blockly.PHP.ORDER_FUNCTION_CALL) || 'array()';
|
||||
|
||||
var code;
|
||||
if (operator == 'FIRST'){
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'indexOf',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'($list, $item) {',
|
||||
' for($i=0; $i < count($list); $i++){',
|
||||
' if ($list[$i] == $item) { return $i + 1; }',
|
||||
' }',
|
||||
' return 0;',
|
||||
'}']);
|
||||
code = functionName + '(' + argument1 + ', ' + argument0 + ')';
|
||||
} else {
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'lastIndexOf',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'($list, $item) {',
|
||||
' $last = -1;',
|
||||
' for($i=0; $i < count($list); $i++){',
|
||||
' if ($list[$i] == $item) { $last = $i; }',
|
||||
' }',
|
||||
' return $last;',
|
||||
'}']);
|
||||
code = functionName + '(' + argument1 + ', ' + argument0 + ') + 1';
|
||||
}
|
||||
|
||||
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
Blockly.PHP['lists_getIndex'] = function(block) {
|
||||
// Get element at index.
|
||||
// Note: Until January 2013 this block did not have MODE or WHERE inputs.
|
||||
var mode = block.getFieldValue('MODE') || 'GET';
|
||||
var where = block.getFieldValue('WHERE') || 'FROM_START';
|
||||
var at = Blockly.PHP.valueToCode(block, 'AT',
|
||||
Blockly.PHP.ORDER_UNARY_NEGATION) || '1';
|
||||
var list = Blockly.PHP.valueToCode(block, 'VALUE',
|
||||
Blockly.PHP.ORDER_FUNCTION_CALL) || '[]';
|
||||
Blockly.PHP.ORDER_FUNCTION_CALL) || 'array()';
|
||||
|
||||
if (where == 'FIRST') {
|
||||
if (mode == 'GET') {
|
||||
var code = list + '[0]';
|
||||
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
} else if (mode == 'GET_REMOVE') {
|
||||
var code = 'array_shift(' + list + ', 1)';
|
||||
var code = 'array_shift(' + list + ')';
|
||||
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
} else if (mode == 'REMOVE') {
|
||||
var code = 'array_shift(' + list + ', 1)';
|
||||
var code = 'array_shift(' + list + ');\n';
|
||||
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
}
|
||||
} else if (where == 'LAST') {
|
||||
if (mode == 'GET') {
|
||||
@@ -179,7 +204,7 @@ Blockly.PHP['lists_setIndex'] = function(block) {
|
||||
// Set element at index.
|
||||
// Note: Until February 2013 this block did not have MODE or WHERE inputs.
|
||||
var list = Blockly.PHP.valueToCode(block, 'LIST',
|
||||
Blockly.PHP.ORDER_MEMBER) || '[]';
|
||||
Blockly.PHP.ORDER_MEMBER) || 'array()';
|
||||
var mode = block.getFieldValue('MODE') || 'GET';
|
||||
var where = block.getFieldValue('WHERE') || 'FROM_START';
|
||||
var at = Blockly.PHP.valueToCode(block, 'AT',
|
||||
@@ -192,7 +217,7 @@ Blockly.PHP['lists_setIndex'] = function(block) {
|
||||
if (list.match(/^\w+$/)) {
|
||||
return '';
|
||||
}
|
||||
var listVar = Blockly.PHP.getDistinctName(
|
||||
var listVar = Blockly.PHP.variableDB_.getDistinctName(
|
||||
'tmp_list', Blockly.Variables.NAME_TYPE);
|
||||
var code = listVar + ' = ' + list + ';\n';
|
||||
list = listVar;
|
||||
@@ -210,7 +235,7 @@ Blockly.PHP['lists_setIndex'] = function(block) {
|
||||
code += list + '[count(' + list + ') - 1] = ' + value + ';\n';
|
||||
return code;
|
||||
} else if (mode == 'INSERT') {
|
||||
return list + 'array_push(' + list + ', ' + value + ');\n';
|
||||
return 'array_push(' + list + ', ' + value + ');\n';
|
||||
}
|
||||
} else if (where == 'FROM_START') {
|
||||
// Blockly uses one-based indicies.
|
||||
@@ -237,7 +262,7 @@ Blockly.PHP['lists_setIndex'] = function(block) {
|
||||
}
|
||||
} else if (where == 'RANDOM') {
|
||||
var code = cacheList();
|
||||
var xVar = Blockly.PHP.getDistinctName(
|
||||
var xVar = Blockly.PHP.variableDB_.getDistinctName(
|
||||
'tmp_x', Blockly.Variables.NAME_TYPE);
|
||||
code += xVar + ' = rand(0, count(' + list + ')-1);\n';
|
||||
if (mode == 'SET') {
|
||||
@@ -254,7 +279,7 @@ Blockly.PHP['lists_setIndex'] = function(block) {
|
||||
Blockly.PHP['lists_getSublist'] = function(block) {
|
||||
// Get sublist.
|
||||
var list = Blockly.PHP.valueToCode(block, 'LIST',
|
||||
Blockly.PHP.ORDER_MEMBER) || '[]';
|
||||
Blockly.PHP.ORDER_MEMBER) || 'array()';
|
||||
var where1 = block.getFieldValue('WHERE1');
|
||||
var where2 = block.getFieldValue('WHERE2');
|
||||
var at1 = Blockly.PHP.valueToCode(block, 'AT1',
|
||||
@@ -262,7 +287,7 @@ Blockly.PHP['lists_getSublist'] = function(block) {
|
||||
var at2 = Blockly.PHP.valueToCode(block, 'AT2',
|
||||
Blockly.PHP.ORDER_NONE) || '1';
|
||||
if (where1 == 'FIRST' && where2 == 'LAST') {
|
||||
var code = list + '.concat()';
|
||||
var code = list;
|
||||
} else {
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'lists_get_sublist',
|
||||
@@ -311,7 +336,7 @@ Blockly.PHP['lists_split'] = function(block) {
|
||||
var functionName = 'explode';
|
||||
} else if (mode == 'JOIN') {
|
||||
if (!value_input) {
|
||||
value_input = '[]';
|
||||
value_input = 'array()';
|
||||
}
|
||||
var functionName = 'implode';
|
||||
} else {
|
||||
|
||||
@@ -34,7 +34,7 @@ Blockly.PHP['controls_repeat'] = function(block) {
|
||||
var repeats = Number(block.getFieldValue('TIMES'));
|
||||
var branch = Blockly.PHP.statementToCode(block, 'DO');
|
||||
branch = Blockly.PHP.addLoopTrap(branch, block.id);
|
||||
var loopVar = Blockly.PHP.getDistinctName(
|
||||
var loopVar = Blockly.PHP.variableDB_.getDistinctName(
|
||||
'count', Blockly.Variables.NAME_TYPE);
|
||||
var code = 'for (' + loopVar + ' = 0; ' +
|
||||
loopVar + ' < ' + repeats + '; ' +
|
||||
@@ -50,11 +50,11 @@ Blockly.PHP['controls_repeat_ext'] = function(block) {
|
||||
var branch = Blockly.PHP.statementToCode(block, 'DO');
|
||||
branch = Blockly.PHP.addLoopTrap(branch, block.id);
|
||||
var code = '';
|
||||
var loopVar = Blockly.PHP.getDistinctName(
|
||||
var loopVar = Blockly.PHP.variableDB_.getDistinctName(
|
||||
'count', Blockly.Variables.NAME_TYPE);
|
||||
var endVar = repeats;
|
||||
if (!repeats.match(/^\w+$/) && !Blockly.isNumber(repeats)) {
|
||||
var endVar = Blockly.PHP.getDistinctName(
|
||||
var endVar = Blockly.PHP.variableDB_.getDistinctName(
|
||||
'repeat_end', Blockly.Variables.NAME_TYPE);
|
||||
code += endVar + ' = ' + repeats + ';\n';
|
||||
}
|
||||
@@ -81,7 +81,7 @@ Blockly.PHP['controls_whileUntil'] = function(block) {
|
||||
|
||||
Blockly.PHP['controls_for'] = function(block) {
|
||||
// For loop.
|
||||
var variable0 = Blockly.PHP.getName(
|
||||
var variable0 = Blockly.PHP.variableDB_.getName(
|
||||
block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
|
||||
var argument0 = Blockly.PHP.valueToCode(block, 'FROM',
|
||||
Blockly.PHP.ORDER_ASSIGNMENT) || '0';
|
||||
@@ -111,19 +111,19 @@ Blockly.PHP['controls_for'] = function(block) {
|
||||
// Cache non-trivial values to variables to prevent repeated look-ups.
|
||||
var startVar = argument0;
|
||||
if (!argument0.match(/^\w+$/) && !Blockly.isNumber(argument0)) {
|
||||
startVar = Blockly.PHP.getDistinctName(
|
||||
startVar = Blockly.PHP.variableDB_.getDistinctName(
|
||||
variable0 + '_start', Blockly.Variables.NAME_TYPE);
|
||||
code += startVar + ' = ' + argument0 + ';\n';
|
||||
}
|
||||
var endVar = argument1;
|
||||
if (!argument1.match(/^\w+$/) && !Blockly.isNumber(argument1)) {
|
||||
var endVar = Blockly.PHP.getDistinctName(
|
||||
var endVar = Blockly.PHP.variableDB_.getDistinctName(
|
||||
variable0 + '_end', Blockly.Variables.NAME_TYPE);
|
||||
code += endVar + ' = ' + argument1 + ';\n';
|
||||
}
|
||||
// Determine loop direction at start, in case one of the bounds
|
||||
// changes during loop execution.
|
||||
var incVar = Blockly.PHP.getDistinctName(
|
||||
var incVar = Blockly.PHP.variableDB_.getDistinctName(
|
||||
variable0 + '_inc', Blockly.Variables.NAME_TYPE);
|
||||
code += incVar + ' = ';
|
||||
if (Blockly.isNumber(increment)) {
|
||||
@@ -146,7 +146,7 @@ Blockly.PHP['controls_for'] = function(block) {
|
||||
|
||||
Blockly.PHP['controls_forEach'] = function(block) {
|
||||
// For each loop.
|
||||
var variable0 = Blockly.PHP.getName(
|
||||
var variable0 = Blockly.PHP.variableDB_.getName(
|
||||
block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
|
||||
var argument0 = Blockly.PHP.valueToCode(block, 'LIST',
|
||||
Blockly.PHP.ORDER_ASSIGNMENT) || '[]';
|
||||
|
||||
@@ -52,7 +52,7 @@ Blockly.PHP['math_arithmetic'] = function(block) {
|
||||
var code;
|
||||
// Power in PHP requires a special case since it has no operator.
|
||||
if (!operator) {
|
||||
code = 'Math.pow(' + argument0 + ', ' + argument1 + ')';
|
||||
code = 'pow(' + argument0 + ', ' + argument1 + ')';
|
||||
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
}
|
||||
code = argument0 + operator + argument1;
|
||||
@@ -146,8 +146,8 @@ Blockly.PHP['math_single'] = function(block) {
|
||||
Blockly.PHP['math_constant'] = function(block) {
|
||||
// Constants: PI, E, the Golden Ratio, sqrt(2), 1/sqrt(2), INFINITY.
|
||||
var CONSTANTS = {
|
||||
'PI': ['pi()', Blockly.PHP.ORDER_FUNCTION_CALL],
|
||||
'E': ['exp()', Blockly.PHP.ORDER_FUNCTION_CALL],
|
||||
'PI': ['M_PI', Blockly.PHP.ORDER_ATOMIC],
|
||||
'E': ['M_E', Blockly.PHP.ORDER_ATOMIC],
|
||||
'GOLDEN_RATIO':
|
||||
['(1 + sqrt(5)) / 2', Blockly.PHP.ORDER_DIVISION],
|
||||
'SQRT2': ['M_SQRT2', Blockly.PHP.ORDER_ATOMIC],
|
||||
@@ -164,7 +164,32 @@ Blockly.PHP['math_number_property'] = function(block) {
|
||||
Blockly.PHP.ORDER_MODULUS) || '0';
|
||||
var dropdown_property = block.getFieldValue('PROPERTY');
|
||||
var code;
|
||||
|
||||
if (dropdown_property == 'PRIME') {
|
||||
// Prime is a special case as it is not a one-liner test.
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'math_isPrime',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + '($n) {',
|
||||
' // https://en.wikipedia.org/wiki/Primality_test#Naive_methods',
|
||||
' if ($n == 2 || $n == 3) {',
|
||||
' return true;',
|
||||
' }',
|
||||
' // False if n is NaN, negative, is 1, or not whole.',
|
||||
' // And false if n is divisible by 2 or 3.',
|
||||
' if (!is_numeric($n) || $n <= 1 || $n % 1 != 0 || $n % 2 == 0 ||' +
|
||||
' $n % 3 == 0) {',
|
||||
' return false;',
|
||||
' }',
|
||||
' // Check all the numbers of form 6k +/- 1, up to sqrt(n).',
|
||||
' for ($x = 6; $x <= sqrt($n) + 1; $x += 6) {',
|
||||
' if ($n % ($x - 1) == 0 || $n % ($x + 1) == 0) {',
|
||||
' return false;',
|
||||
' }',
|
||||
' }',
|
||||
' return true;',
|
||||
'}']);
|
||||
code = functionName + '(' + number_to_check + ')';
|
||||
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
}
|
||||
switch (dropdown_property) {
|
||||
case 'EVEN':
|
||||
code = number_to_check + ' % 2 == 0';
|
||||
@@ -172,11 +197,8 @@ Blockly.PHP['math_number_property'] = function(block) {
|
||||
case 'ODD':
|
||||
code = number_to_check + ' % 2 == 1';
|
||||
break;
|
||||
case 'PRIME':
|
||||
code = 'mp_prob_prime('+number_to_check + ')';
|
||||
break;
|
||||
case 'WHOLE':
|
||||
code = number_to_check + ' % 1 == 0';
|
||||
code = 'is_int(' + number_to_check + ')';
|
||||
break;
|
||||
case 'POSITIVE':
|
||||
code = number_to_check + ' > 0';
|
||||
@@ -197,7 +219,7 @@ Blockly.PHP['math_change'] = function(block) {
|
||||
// Add to a variable in place.
|
||||
var argument0 = Blockly.PHP.valueToCode(block, 'DELTA',
|
||||
Blockly.PHP.ORDER_ADDITION) || '0';
|
||||
var varName = Blockly.PHP.getName(
|
||||
var varName = Blockly.PHP.variableDB_.getName(
|
||||
block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
|
||||
return varName + ' += ' + argument0 + ';\n';
|
||||
};
|
||||
@@ -228,7 +250,6 @@ Blockly.PHP['math_on_list'] = function(block) {
|
||||
code = 'max(' + list + ')';
|
||||
break;
|
||||
case 'AVERAGE':
|
||||
// math_median([null,null,1,3]) == 2.0.
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'math_mean',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
@@ -240,14 +261,13 @@ Blockly.PHP['math_on_list'] = function(block) {
|
||||
code = functionName + '(' + list + ')';
|
||||
break;
|
||||
case 'MEDIAN':
|
||||
// math_median([null,null,1,3]) == 2.0.
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'math_median',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'($myList) {',
|
||||
' rsort($myList);',
|
||||
' $middle = round(count($myList) / 2);',
|
||||
' return $myList[$middle-1]; ',
|
||||
'($arr) {',
|
||||
' sort($arr,SORT_NUMERIC);',
|
||||
' return (count($arr) % 2) ? $arr[floor(count($arr)/2)] : ',
|
||||
' ($arr[floor(count($arr)/2)] + $arr[floor(count($arr)/2) - 1]) / 2;',
|
||||
'}']);
|
||||
list = Blockly.PHP.valueToCode(block, 'LIST',
|
||||
Blockly.PHP.ORDER_NONE) || '[]';
|
||||
@@ -264,23 +284,33 @@ Blockly.PHP['math_on_list'] = function(block) {
|
||||
' $v = array_count_values($values);',
|
||||
' arsort($v);',
|
||||
' foreach($v as $k => $v){$total = $k; break;}',
|
||||
' return $total;',
|
||||
' return array($total);',
|
||||
'}']);
|
||||
list = Blockly.PHP.valueToCode(block, 'LIST',
|
||||
Blockly.PHP.ORDER_NONE) || '[]';
|
||||
code = functionName + '(' + list + ')';
|
||||
break;
|
||||
case 'STD_DEV':
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'math_standard_deviation',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'($numbers) {',
|
||||
' $n = count($numbers);',
|
||||
' if (!$n) return null;',
|
||||
' $mean = array_sum($numbers) / count($numbers);',
|
||||
' foreach($numbers as $key => $num) $devs[$key] = pow($num - $mean, 2);',
|
||||
' return sqrt(array_sum($devs) / (count($devs) - 1));',
|
||||
'}']);
|
||||
list = Blockly.PHP.valueToCode(block, 'LIST',
|
||||
Blockly.PHP.ORDER_MEMBER) || 'array()';
|
||||
code = 'stats_standard_deviation(' + list + ')';
|
||||
Blockly.PHP.ORDER_NONE) || '[]';
|
||||
code = functionName + '(' + list + ')';
|
||||
break;
|
||||
case 'RANDOM':
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'math_random_list',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'($list) {',
|
||||
' $x = floor(rand() * count($list));',
|
||||
' $x = rand(0, count($list)-1);',
|
||||
' return $list[$x];',
|
||||
'}']);
|
||||
list = Blockly.PHP.valueToCode(block, 'LIST',
|
||||
|
||||
@@ -30,7 +30,22 @@ goog.require('Blockly.PHP');
|
||||
|
||||
Blockly.PHP['procedures_defreturn'] = function(block) {
|
||||
// Define a procedure with a return value.
|
||||
var funcName = Blockly.PHP.getName(
|
||||
// First, add a 'global' statement for every variable that is assigned.
|
||||
var globals = Blockly.Variables.allVariables(block);
|
||||
for (var i = globals.length - 1; i >= 0; i--) {
|
||||
var varName = globals[i];
|
||||
if (block.arguments_.indexOf(varName) == -1) {
|
||||
globals[i] = Blockly.PHP.variableDB_.getName(varName,
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
} else {
|
||||
// This variable is actually a parameter name. Do not include it in
|
||||
// the list of globals, thus allowing it be of local scope.
|
||||
globals.splice(i, 1);
|
||||
}
|
||||
}
|
||||
globals = globals.length ? ' global ' + globals.join(', ') + ';\n' : '';
|
||||
|
||||
var funcName = Blockly.PHP.variableDB_.getName(
|
||||
block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE);
|
||||
var branch = Blockly.PHP.statementToCode(block, 'STACK');
|
||||
if (Blockly.PHP.STATEMENT_PREFIX) {
|
||||
@@ -49,11 +64,11 @@ Blockly.PHP['procedures_defreturn'] = function(block) {
|
||||
}
|
||||
var args = [];
|
||||
for (var x = 0; x < block.arguments_.length; x++) {
|
||||
args[x] = Blockly.PHP.getName(block.arguments_[x],
|
||||
args[x] = Blockly.PHP.variableDB_.getName(block.arguments_[x],
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
}
|
||||
var code = 'function ' + funcName + '(' + args.join(', ') + ') {\n' +
|
||||
branch + returnValue + '}';
|
||||
globals + branch + returnValue + '}';
|
||||
code = Blockly.PHP.scrub_(block, code);
|
||||
Blockly.PHP.definitions_[funcName] = code;
|
||||
return null;
|
||||
@@ -66,7 +81,7 @@ Blockly.PHP['procedures_defnoreturn'] =
|
||||
|
||||
Blockly.PHP['procedures_callreturn'] = function(block) {
|
||||
// Call a procedure with a return value.
|
||||
var funcName = Blockly.PHP.getName(
|
||||
var funcName = Blockly.PHP.variableDB_.getName(
|
||||
block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE);
|
||||
var args = [];
|
||||
for (var x = 0; x < block.arguments_.length; x++) {
|
||||
@@ -79,7 +94,7 @@ Blockly.PHP['procedures_callreturn'] = function(block) {
|
||||
|
||||
Blockly.PHP['procedures_callnoreturn'] = function(block) {
|
||||
// Call a procedure with no return value.
|
||||
var funcName = Blockly.PHP.getName(
|
||||
var funcName = Blockly.PHP.variableDB_.getName(
|
||||
block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE);
|
||||
var args = [];
|
||||
for (var x = 0; x < block.arguments_.length; x++) {
|
||||
|
||||
@@ -58,14 +58,14 @@ Blockly.PHP['text_join'] = function(block) {
|
||||
code[n] = Blockly.PHP.valueToCode(block, 'ADD' + n,
|
||||
Blockly.PHP.ORDER_COMMA) || '\'\'';
|
||||
}
|
||||
code = 'implode(\',\'' + code.join(',') + ')';
|
||||
code = 'implode(\'\', array(' + code.join(',') + '))';
|
||||
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.PHP['text_append'] = function(block) {
|
||||
// Append to a variable in place.
|
||||
var varName = Blockly.PHP.getName(
|
||||
var varName = Blockly.PHP.variableDB_.getName(
|
||||
block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
|
||||
var argument0 = Blockly.PHP.valueToCode(block, 'TEXT',
|
||||
Blockly.PHP.ORDER_NONE) || '\'\'';
|
||||
@@ -94,7 +94,16 @@ Blockly.PHP['text_indexOf'] = function(block) {
|
||||
Blockly.PHP.ORDER_FUNCTION_CALL) || '\'\'';
|
||||
var argument1 = Blockly.PHP.valueToCode(block, 'VALUE',
|
||||
Blockly.PHP.ORDER_FUNCTION_CALL) || '\'\'';
|
||||
var code = operator + '(' + argument0 + ', ' + argument1 + ') + 1';
|
||||
var code = operator + '(' + argument1 + ', ' + argument0 + ') + 1';
|
||||
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
block.getFieldValue('END')=='FIRST'?'text_indexOf':'text_lastIndexOf',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'($text, $search) {',
|
||||
' $pos = ' + operator + '($text, $search);',
|
||||
' return $pos===false?0:$pos+1;',
|
||||
'}']);
|
||||
code = functionName + '(' + argument1 + ', ' + argument0 + ')';
|
||||
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
@@ -156,6 +165,15 @@ Blockly.PHP['text_getSubstring'] = function(block) {
|
||||
'text_get_substring',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'($text, $where1, $at1, $where2, $at2) {',
|
||||
' if ($where2 == \'FROM_START\') {',
|
||||
' $at2--;',
|
||||
' } else if ($where2 == \'FROM_END\') {',
|
||||
' $at2 = $at2 - $at1;',
|
||||
' } else if ($where2 == \'FIRST\') {',
|
||||
' $at2 = 0;',
|
||||
' } else if ($where2 == \'LAST\') {',
|
||||
' $at2 = strlen($text);',
|
||||
' } else { $at2 = 0; }',
|
||||
' if ($where1 == \'FROM_START\') {',
|
||||
' $at1--;',
|
||||
' } else if ($where1 == \'FROM_END\') {',
|
||||
@@ -165,14 +183,6 @@ Blockly.PHP['text_getSubstring'] = function(block) {
|
||||
' } else if ($where1 == \'LAST\') {',
|
||||
' $at1 = strlen($text) - 1;',
|
||||
' } else { $at1 = 0; }',
|
||||
' if ($where2 == \'FROM_START\') {',
|
||||
' } else if ($where2 == \'FROM_END\') {',
|
||||
' $at2 = strlen($text) - $at2;',
|
||||
' } else if ($where2 == \'FIRST\') {',
|
||||
' $at2 = 0;',
|
||||
' } else if ($where2 == \'LAST\') {',
|
||||
' $at2 = strlen($text);',
|
||||
' } else { $at2 = 0; }',
|
||||
' return substr($text, $at1, $at2);',
|
||||
'}']);
|
||||
var code = functionName + '(' + text + ', \'' +
|
||||
@@ -195,7 +205,7 @@ Blockly.PHP['text_changeCase'] = function(block) {
|
||||
} else if (block.getFieldValue('CASE')=='TITLECASE') {
|
||||
var argument0 = Blockly.PHP.valueToCode(block, 'TEXT',
|
||||
Blockly.PHP.ORDER_FUNCTION_CALL) || '\'\'';
|
||||
code = 'ucwords(' + argument0 + ')';
|
||||
code = 'ucwords(strtolower(' + argument0 + '))';
|
||||
}
|
||||
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
@@ -31,7 +31,8 @@ goog.require('Blockly.PHP');
|
||||
|
||||
Blockly.PHP['variables_get'] = function(block) {
|
||||
// Variable getter.
|
||||
var code = '$' + block.getFieldValue('VAR');
|
||||
var code = Blockly.PHP.variableDB_.getName(block.getFieldValue('VAR'),
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
return [code, Blockly.PHP.ORDER_ATOMIC];
|
||||
};
|
||||
|
||||
@@ -39,7 +40,7 @@ Blockly.PHP['variables_set'] = function(block) {
|
||||
// Variable setter.
|
||||
var argument0 = Blockly.PHP.valueToCode(block, 'VALUE',
|
||||
Blockly.PHP.ORDER_ASSIGNMENT) || '0';
|
||||
var varName = Blockly.PHP.getName(
|
||||
var varName = Blockly.PHP.variableDB_.getName(
|
||||
block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
|
||||
return varName + ' = ' + argument0 + ';\n';
|
||||
};
|
||||
@@ -24,6 +24,18 @@
|
||||
<script src="../../generators/python/colour.js"></script>
|
||||
<script src="../../generators/python/variables.js"></script>
|
||||
<script src="../../generators/python/procedures.js"></script>
|
||||
|
||||
<script src="../../generators/php.js"></script>
|
||||
<script src="unittest_php.js"></script>
|
||||
<script src="../../generators/php/logic.js"></script>
|
||||
<script src="../../generators/php/loops.js"></script>
|
||||
<script src="../../generators/php/math.js"></script>
|
||||
<script src="../../generators/php/text.js"></script>
|
||||
<script src="../../generators/php/lists.js"></script>
|
||||
<script src="../../generators/php/colour.js"></script>
|
||||
<script src="../../generators/php/variables.js"></script>
|
||||
<script src="../../generators/php/procedures.js"></script>
|
||||
|
||||
<script src="../../generators/dart.js"></script>
|
||||
<script src="unittest_dart.js"></script>
|
||||
<script src="../../generators/dart/logic.js"></script>
|
||||
@@ -126,6 +138,11 @@ function toPython() {
|
||||
setOutput(code);
|
||||
}
|
||||
|
||||
function toPhp() {
|
||||
var code = Blockly.PHP.workspaceToCode(workspace);
|
||||
setOutput(code);
|
||||
}
|
||||
|
||||
function toDart() {
|
||||
var code = Blockly.Dart.workspaceToCode(workspace);
|
||||
setOutput(code);
|
||||
@@ -406,6 +423,7 @@ h1 {
|
||||
<input type="button" value="XML" onclick="toXml()">
|
||||
<input type="button" value="JavaScript" onclick="toJavaScript()">
|
||||
<input type="button" value="Python" onclick="toPython()">
|
||||
<input type="button" value="PHP" onclick="toPhp()">
|
||||
<input type="button" value="Dart" onclick="toDart()">
|
||||
</p>
|
||||
</td></tr><tr><td height="99%">
|
||||
|
||||
162
tests/generators/unittest_php.js
Normal file
162
tests/generators/unittest_php.js
Normal file
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
* @license
|
||||
* Visual Blocks Language
|
||||
*
|
||||
* Copyright 2015 Google Inc.
|
||||
* https://developers.google.com/blockly/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Generating PHP for unit test blocks.
|
||||
* @author daarond@gmail.com (Neil Fraser)
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
Blockly.PHP['unittest_main'] = function(block) {
|
||||
// Container for unit tests.
|
||||
var resultsVar = Blockly.PHP.variableDB_.getName('unittestResults',
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'unittest_report',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + '() {',
|
||||
'global ' + resultsVar + ';',
|
||||
' // Create test report.',
|
||||
' $report = array();',
|
||||
' $summary = array();',
|
||||
' $fails = 0;',
|
||||
' for ($x = 0; $x < count(' + resultsVar + '); $x++) {',
|
||||
' if (' + resultsVar + '[$x][0]) {',
|
||||
' array_push($summary, ".");',
|
||||
' } else {',
|
||||
' array_push($summary, "F");',
|
||||
' $fails++;',
|
||||
' array_push($report,"");',
|
||||
' array_push($report, "FAIL: " . ' + resultsVar + '[$x][2]);',
|
||||
' array_push($report, ' + resultsVar + '[$x][1]);',
|
||||
' }',
|
||||
' }',
|
||||
' array_unshift($report, implode("",$summary));',
|
||||
' array_push($report, "");',
|
||||
' array_push($report, "Number of tests run: " . count(' + resultsVar + '));',
|
||||
' array_push($report, "");',
|
||||
' if ($fails) {',
|
||||
' array_push($report, "FAILED (failures=" . $fails + ")");',
|
||||
' } else {',
|
||||
' array_push($report, "OK");',
|
||||
' }',
|
||||
' return implode("\\n", $report);',
|
||||
'}']);
|
||||
// Setup global to hold test results.
|
||||
var code = resultsVar + ' = array();\n';
|
||||
// Run tests (unindented).
|
||||
code += Blockly.PHP.statementToCode(block, 'DO')
|
||||
.replace(/^ /, '').replace(/\n /g, '\n');
|
||||
var reportVar = Blockly.PHP.variableDB_.getDistinctName(
|
||||
'report', Blockly.Variables.NAME_TYPE);
|
||||
code += reportVar + ' = ' + functionName + '();\n';
|
||||
// Destroy results.
|
||||
code += resultsVar + ' = null;\n';
|
||||
// Send the report to the console (that's where errors will go anyway).
|
||||
code += 'print(' + reportVar + ');\n';
|
||||
return code;
|
||||
};
|
||||
|
||||
Blockly.PHP['unittest_main'].defineAssert_ = function(block) {
|
||||
var resultsVar = Blockly.PHP.variableDB_.getName('unittestResults',
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'assertEquals',
|
||||
[ ' function equals($a, $b) {',
|
||||
' if ($a === $b) {',
|
||||
' return true;',
|
||||
' } else if ((is_numeric($a)) && (is_numeric($b)) &&',
|
||||
' (round($a,15) == round($b,15))) {',
|
||||
' return true;',
|
||||
' } else if (is_array($a) && is_array($b)) {',
|
||||
' if (count($a) != count($b)) {',
|
||||
' return false;',
|
||||
' }',
|
||||
' for ($i = 0; $i < count($a); $i++) {',
|
||||
' if (!equals($a[$i], $b[$i])) {',
|
||||
' return false;',
|
||||
' }',
|
||||
' }',
|
||||
' return true;',
|
||||
' }',
|
||||
' return false;',
|
||||
' }',
|
||||
'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'($actual, $expected, $message) {',
|
||||
'global ' + resultsVar + ';',
|
||||
' // Asserts that a value equals another value.',
|
||||
' if (!is_array(' + resultsVar + ')) {',
|
||||
' throw new Exception("Orphaned assert: " . $message);',
|
||||
' }',
|
||||
' if (equals($actual, $expected)) {',
|
||||
' array_push(' + resultsVar + ', [true, "OK", $message]);',
|
||||
' } else {',
|
||||
' array_push(' + resultsVar + ', [false, ' +
|
||||
'"Expected: " . $expected . "\\nActual: " . $actual, $message]);',
|
||||
' }',
|
||||
'}']);
|
||||
return functionName;
|
||||
};
|
||||
|
||||
Blockly.PHP['unittest_assertequals'] = function(block) {
|
||||
// Asserts that a value equals another value.
|
||||
var message = Blockly.PHP.quote_(block.getFieldValue('MESSAGE'));
|
||||
var actual = Blockly.PHP.valueToCode(block, 'ACTUAL',
|
||||
Blockly.PHP.ORDER_COMMA) || 'null';
|
||||
var expected = Blockly.PHP.valueToCode(block, 'EXPECTED',
|
||||
Blockly.PHP.ORDER_COMMA) || 'null';
|
||||
return Blockly.PHP['unittest_main'].defineAssert_() +
|
||||
'(' + actual + ', ' + expected + ', ' + message + ');\n';
|
||||
};
|
||||
|
||||
Blockly.PHP['unittest_assertvalue'] = function(block) {
|
||||
// Asserts that a value is true, false, or null.
|
||||
var message = Blockly.PHP.quote_(block.getFieldValue('MESSAGE'));
|
||||
var actual = Blockly.PHP.valueToCode(block, 'ACTUAL',
|
||||
Blockly.PHP.ORDER_COMMA) || 'null';
|
||||
var expected = block.getFieldValue('EXPECTED');
|
||||
if (expected == 'TRUE') {
|
||||
expected = 'true';
|
||||
} else if (expected == 'FALSE') {
|
||||
expected = 'false';
|
||||
} else if (expected == 'NULL') {
|
||||
expected = 'null';
|
||||
}
|
||||
return Blockly.PHP['unittest_main'].defineAssert_() +
|
||||
'(' + actual + ', ' + expected + ', ' + message + ');\n';
|
||||
};
|
||||
|
||||
Blockly.PHP['unittest_fail'] = function(block) {
|
||||
// Always assert an error.
|
||||
var resultsVar = Blockly.PHP.variableDB_.getName('unittestResults',
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
var message = Blockly.PHP.quote_(block.getFieldValue('MESSAGE'));
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'unittest_fail',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'($message) {',
|
||||
'global ' + resultsVar + ';',
|
||||
' // Always assert an error.',
|
||||
' if (!' + resultsVar + ') {',
|
||||
' throw new Exception("Orphaned assert fail: " . $message);',
|
||||
' }',
|
||||
' array_push(' + resultsVar + ', [false, "Fail.", $message]);',
|
||||
'}']);
|
||||
return functionName + '(' + message + ');\n';
|
||||
};
|
||||
Reference in New Issue
Block a user