Commit 5aa375bc authored by carlosperate's avatar carlosperate

Updates for static typing to the variables block and generators:

- Added warnings for setting variables to a different type than first instance
- Type finding for the get variable block
- Corrected the arduino types array
- Updated the cast block to return type as defined by cast
- Updated wording of the cast block
parent 5487d900
......@@ -25,8 +25,7 @@ Blockly.Blocks['variables_set_type'] = {
init: function() {
this.setHelpUrl('http://arduino.cc/en/Reference/HomePage');
this.setColour(Blockly.Blocks.Arduino.variables.HUE);
this.appendValueInput("VARIABLE_SETTYPE_INPUT", '')
.appendField("set");
this.appendValueInput("VARIABLE_SETTYPE_INPUT", '');
this.appendDummyInput("")
.appendField("as")
.appendField(new Blockly.FieldDropdown(profile.default.types),
......@@ -34,5 +33,12 @@ Blockly.Blocks['variables_set_type'] = {
this.setInputsInline(true);
this.setOutput(true);
this.setTooltip('Sets a value to a specific type');
},
/**
* Assigns a type to the block based on the selected type to cast.
* @this Blockly.Block
*/
getType: function() {
return this.getFieldValue('VARIABLE_SETTYPE_TYPE');
}
};
......@@ -84,6 +84,48 @@ Blockly.Blocks['variables_get'] = {
xmlBlock.setAttribute('type', this.contextMenuType_);
option.callback = Blockly.ContextMenu.callbackFactory(this, xmlBlock);
options.push(option);
},
/**
* Assigns a type to the variable. In this case we need to find the original
* variable set block for the selected variable and set that type.
* @this Blockly.Block
* @param {Array<string>} existingVars List of variables already defined.
* @return {string} String to indicate the type if it has not been defined
* before.
*/
getVarType: function(existingVars) {
var varName = this.getFieldValue('VAR');
var varType = null;
// Check if variable has been defined already add if it has been.
for (var name in existingVars) {
if (name === varName) {
varType = existingVars[varName];
this.varType = varType;
break;
}
}
// This block needs the variable to be define before use, so warn user.
if (varType == null) {
this.setWarningText('This variable needs to be set to something before' +
' it can be used!');
} else {
this.setWarningText(null);
}
return varType;
},
/**
* Contains the type of the variable selected from the first set block.
*/
varType: 'nonono',
/**
* Retrieves the type of the selected variable, defined at getVarType.
* @this Blockly.Block
*/
getType: function(existingVars) {
return this.varType;
}
};
......@@ -131,23 +173,54 @@ Blockly.Blocks['variables_set'] = {
customContextMenu: Blockly.Blocks['variables_get'].customContextMenu,
/**
* Searches through the nested blocks to find a variable type.
* @this Blockly.Blocks
* @this Blockly.Block
* @param {Array<string>} existingVars List of variables already defined.
* @return {string} String to indicate the type if it has not been defined
* before.
*/
getVarType: function() {
var myType = 'nonono';
getVarType: function(existingVars) {
var varName = this.getFieldValue('VAR');
var varType = null;
// Check what this block type should be
var nextBlock = [this];
while ((nextBlock[0].getType == null) &&
(nextBlock[0].getChildren().length > 0)) {
nextBlock = nextBlock[0].getChildren();
}
if (nextBlock[0] === this) {
myType = 'defineme';
// Set variable block is empty
varType = 'defineme';
} else {
var func = nextBlock[0].getType;
if (func) {
myType = nextBlock[0].getType();
varType = nextBlock[0].getType();
} else {
varType = 'innerBlockNoType';
}
}
return myType;
// Check if variable has been defined already
var unique = true;
for (var name in existingVars) {
if (name == varName) {
unique = false;
break;
}
}
// Only set the type if the variable has not been defined before
if (unique) {
this.setWarningText(null);
return varType;
} else if ((existingVars[varName] != varType) && (nextBlock[0] != this)) {
this.setWarningText('This block is using a different type than what ' +
'was set on the first use of this variable.\nFirst use type: ' +
existingVars[varName] + '\nThis block type: ' + varType);
return null;
} else {
this.setWarningText(null);
return null;
}
}
};
......@@ -86,8 +86,7 @@ var profile = {
["Integer", "int"], ["Unsigned Integer", "unsigned int"],
["Word", "word"], ["Long", "long"],
["Unsigned Long", "unsigned long"], ["Short", "short"],
["Float", "float"], ["Double", "double"], ["String", "String"],
["Char Array", "string"], ["Array", "array"]],
["Float", "float"], ["Double", "double"], ["String", "String"]],
spi_clock_divide: [['2 (8MHz)', 'SPI_CLOCK_DIV2'],
['4 (4MHz)', 'SPI_CLOCK_DIV4'],
['8 (2MHz)', 'SPI_CLOCK_DIV8'],
......@@ -114,7 +113,7 @@ var profile = {
//same serial
//same types
}
}
};
// Set default profile to arduino standard-compatible board
profile["default"] = profile["arduino"];
......@@ -142,31 +141,26 @@ Blockly.Arduino.init = function(opt_workspace) {
Blockly.Arduino.variableDB_.reset();
}
// Iterate through the blocks to capture variables with first value
var variableWithType = Object.create(null);
// Iterate through the blocks to capture variables with first instance type
var variableTypes = Object.create(null);
var blocks = Blockly.mainWorkspace.getAllBlocks();
for (var x = 0; x < blocks.length; x++) {
var getVars = blocks[x].getVars;
if (getVars) {
// Iterate through the variables used in this block
var blockVariables = getVars.call(blocks[x]);
for (var y = 0; y < blockVariables.length; y++) {
// Check if it's the first instance of the new variable name
var unique = true;
for (var name in variableWithType) {
if (name == blockVariables[y]) {
unique = false;
break;
}
}
// If it is the first instance log the variable type
if (unique == true) {
var getType = blocks[x].getVarType;
if (getType) {
variableWithType[blockVariables[y]] = blocks[x].getVarType();
} else {
variableWithType[blockVariables[y]] = 'notdefined';
// Send variable list to getVarType, returns type if first encounter or
// null if already defined.
var getVarType = blocks[x].getVarType;
if (getVarType) {
var varType = getVarType.call(blocks[x], variableTypes);
if (varType != null) {
variableTypes[blockVariables[y]] = varType;
}
} else {
//TODO: Once all static typing is done this will default to 'int'.
variableTypes[blockVariables[y]] = 'getVarTypeNotDef';
}
}
}
......@@ -174,8 +168,8 @@ Blockly.Arduino.init = function(opt_workspace) {
// Set variable declarations
var variableDeclarations = [];
for (var name in variableWithType) {
variableDeclarations.push(variableWithType[name] + ' ' + name + ';');
for (var name in variableTypes) {
variableDeclarations.push(variableTypes[name] + ' ' + name + ';');
}
Blockly.Arduino.definitions_['variables'] =
variableDeclarations.join('\n') + '\n';
......
......@@ -48,6 +48,6 @@ Blockly.Arduino['variables_set_type'] = function(block) {
var argument0 = Blockly.Arduino.valueToCode(block, 'VARIABLE_SETTYPE_INPUT',
Blockly.Arduino.ORDER_ASSIGNMENT) || '0';
var varType = block.getFieldValue('VARIABLE_SETTYPE_TYPE');
var code = '(' + varType + ')' + argument0;
var code = '(' + varType + ')(' + argument0 + ')';
return [code, Blockly.Arduino.ORDER_ATOMIC];
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment