Blockly uygulamaları genellikle çıkış dili olarak JavaScript oluşturur. Bu dil, genellikle bir web sayfasında (aynı veya yerleştirilmiş bir WebView olabilir) çalıştırılır. Diğer tüm oluşturucularda olduğu gibi, ilk adım JavaScript oluşturucuyu eklemektir.
import {javascriptGenerator} from 'blockly/javascript';
Çalışma alanından JavaScript oluşturmak için şu işlevi çağırın:
javascriptGenerator.addReservedWords('code');
var code = javascriptGenerator.workspaceToCode(workspace);
Elde edilen kod, doğrudan hedef web sayfasında yürütülebilir:
try {
eval(code);
} catch (e) {
alert(e);
}
Temel olarak, yukarıdaki snippet yalnızca kodu oluşturur ve değerlendirir. Ancak birkaç iyileştirme yapılmıştır. Bir iyileştirme olarak, değerlendirme try/catch içine alınır. Böylece, çalışma zamanı hataları sessizce başarısız olmak yerine görünür hale gelir. Başka bir iyileştirme olarak, kullanıcının kodunda bu ada sahip bir değişken varsa çakışmak yerine otomatik olarak yeniden adlandırılması için code ayrılmış kelimeler listesine eklenir. Tüm yerel değişkenler bu şekilde ayrılmalıdır.
Öne Çıkarma Blokları
Kod çalışırken yürütülen bloğu vurgulamak, kullanıcıların programlarının davranışını anlamalarına yardımcı olur. JavaScript kodu oluşturulmadan önce STATEMENT_PREFIX ayarlanarak vurgulama ifade bazında yapılabilir:
javascriptGenerator.STATEMENT_PREFIX = 'highlightBlock(%1);\n';
javascriptGenerator.addReservedWords('highlightBlock');
Çalışma alanındaki bloğu işaretlemek için highlightBlock simgesini tanımlayın.
function highlightBlock(id) {
workspace.highlightBlock(id);
}
Bu durumda, her ifadenin önüne highlightBlock('123'); ifadesi eklenir. Burada 123, vurgulanacak bloğun seri numarasıdır.
Sonsuz Döngüler
Sonuçta elde edilen kodun her zaman söz dizimi açısından doğru olduğu garanti edilse de sonsuz döngüler içerebilir. Durdurma sorununu çözmek Blockly'nin kapsamı dışında olduğundan (!), bu durumlarla başa çıkmak için en iyi yaklaşım bir sayaç tutmak ve her yineleme yapıldığında sayacı azaltmaktır.
Bunu yapmak için javascriptGenerator.INFINITE_LOOP_TRAP değerini her döngüye ve her işleve eklenecek bir kod snippet'i olarak ayarlamanız yeterlidir. Örnek:
window.LoopTrap = 1000;
javascriptGenerator.INFINITE_LOOP_TRAP = 'if(--window.LoopTrap == 0) throw "Infinite loop.";\n';
var code = javascriptGenerator.workspaceToCode(workspace);
Örnek
JavaScript oluşturma ve çalıştırma ile ilgili canlı bir demoyu burada bulabilirsiniz.
JS-Interpreter
Kullanıcının bloklarını düzgün bir şekilde çalıştırmak istiyorsanız JS-Interpreter projesini kullanmanız gerekir. Bu proje Blockly'den ayrıdır ancak özellikle Blockly için yazılmıştır.
- Kodu istediğiniz hızda çalıştırın.
- Yürütmeyi duraklatma/devam ettirme/adımlama
- Çalıştırıldıkça blokları vurgulayın.
- Tarayıcının JavaScript'inden tamamen izole edilmiştir.
Çevirmeni çalıştırma
İlk olarak GitHub'dan JS-Interpreter'ı indirin:
Ardından, kodu sayfanıza ekleyin:
<script src="acorn_interpreter.js"></script>
Bu işlevi çağırmanın en basit yöntemi, JavaScript'i oluşturmak, yorumlayıcıyı oluşturmak ve kodu çalıştırmaktır:
var code = javascriptGenerator.workspaceToCode(workspace);
var myInterpreter = new Interpreter(code);
myInterpreter.run();
Step the Interpreter
Kodu daha yavaş veya daha kontrollü bir şekilde yürütmek için run çağrısını, adımlayan bir döngüyle (bu örnekte her 10 ms'de bir adım) değiştirin:
function nextStep() {
if (myInterpreter.step()) {
setTimeout(nextStep, 10);
}
}
nextStep();
Her adımın bir satır veya blok değil, JavaScript'teki anlamsal bir birim olduğunu ve bu birimin son derece ayrıntılı olabileceğini unutmayın.
API ekleme
JS-Interpreter, tarayıcıdan tamamen izole edilmiş bir korumalı alandır. Dış dünyayla işlem yapan tüm bloklar için yorumlayıcıya bir API eklenmesi gerekir. Tam açıklama için JS-Interpreter belgelerine bakın. Ancak başlangıç olarak, uyarı ve istem bloklarını desteklemek için gereken API'yi aşağıda bulabilirsiniz:
function initApi(interpreter, globalObject) {
// Add an API function for the alert() block.
var wrapper = function(text) {
return alert(arguments.length ? text : '');
};
interpreter.setProperty(globalObject, 'alert',
interpreter.createNativeFunction(wrapper));
// Add an API function for the prompt() block.
wrapper = function(text) {
return prompt(text);
};
interpreter.setProperty(globalObject, 'prompt',
interpreter.createNativeFunction(wrapper));
}
Ardından, initApi işlevini iletmek için yorumlayıcı başlatmanızı değiştirin:
var myInterpreter = new Interpreter(code, initApi);
Uyarı ve istem blokları, varsayılan blok kümesinde yorumlayıcı için özel bir API gerektiren tek iki bloktur.
highlightBlock() bağlanıyor
JS-Interpreter'da çalıştırılırken, kullanıcı programda ilerledikçe highlightBlock() hemen, korumalı alanın dışında yürütülmelidir. Bunu yapmak için işlev bağımsız değişkenini yakalamak üzere bir sarmalayıcı işlev highlightBlock() oluşturun ve bunu yerel işlev olarak kaydedin.
function initApi(interpreter, globalObject) {
// Add an API function for highlighting blocks.
var wrapper = function(id) {
return workspace.highlightBlock(id);
};
interpreter.setProperty(globalObject, 'highlightBlock',
interpreter.createNativeFunction(wrapper));
}
Daha karmaşık uygulamalar, bir vurgulama komutuna ulaşılana kadar adımları duraklatmadan tekrar tekrar yürütmek isteyebilir. Bu strateji, satır satır yürütmeyi simüle eder. Aşağıdaki örnekte bu yaklaşım kullanılmaktadır.
JS-Interpreter Örneği
JavaScript'i adım adım yorumlamayla ilgili canlı bir demo burada verilmiştir. Ayrıca bu demoda bekleme bloğu da yer alıyor.Bu, diğer eşzamansız davranışlar (ör. konuşma veya ses, kullanıcı girişi) için kullanılabilecek iyi bir örnek.