Discuss Scratch

goldfish678
Scratcher
1000+ posts

Scratch compiler beta test

Looks amazing. The only complaint I have is the Procd icon and loading screen.

Last edited by goldfish678 (Oct. 12, 2014 00:25:38)

procd
Scratcher
100+ posts

Scratch compiler beta test

The icon can be changed when compiling. What would you suggest for a load screen?
s_federici
Scratcher
500+ posts

Scratch compiler beta test

gtoal wrote:

if you're still interested in seeing (roughly) how a scratch parser works, I just put up my prototype scratch to C code at http://www.gtoal.com/scratch/sb2c/

This is not the full Scratch 2 exe converter, is it? Or, if it is, what is the best (hopefully free) environment to edit, compile and run it? I used to use MS Visual Studio some years ago, but I lost track of the development of C programming environments in the last years :-) Thanks in advance for your help.
gtoal
Scratcher
1000+ posts

Scratch compiler beta test

s_federici wrote:

gtoal wrote:

if you're still interested in seeing (roughly) how a scratch parser works, I just put up my prototype scratch to C code at http://www.gtoal.com/scratch/sb2c/

This is not the full Scratch 2 exe converter, is it? Or, if it is, what is the best (hopefully free) environment to edit, compile and run it? I used to use MS Visual Studio some years ago, but I lost track of the development of C programming environments in the last years :-) Thanks in advance for your help.

No, this won't create anything that you can run. It was a quick proof of concept for me to see how much work might be involved in writing a scratch converter, but that was before I was aware of the work that procd had done which is almost complete, so I'm unlikely to take this any farther. But I thought I might leave it online so that if anyone wanted to play around with this stuff, they could use it for some ideas to get started.

It's just C and should run on any environment, but if you don't have linux you'll need to modify it to read the json file into an array, because I took a unix shortcut and loaded the file by connecting it directly in the virtual memory using mmap. (The bits you would have to modify are all in main() near the end of the file - open/lseek/mmap should be replaced with stdio calls.)

Graham
PS “cc”, a text editor, and possibly “make” are the only IDE you need. These ridiculous GUIs just slow you down and obfuscate what you're actually doing. (A bit like C++ itself)

Last edited by gtoal (Oct. 14, 2014 22:06:02)

procd
Scratcher
100+ posts

Scratch compiler beta test

The following text are my thoughts before I started to write the compiler. Most of the ideas are still present in the compiler. NOt sure ow much sense it will make
ScratchBlock -> Returns ScratchBlock when Invoked to allow chaining

ScratchBlock is a function or ScratchBlock is a Value



abstract ScratchBlock

Concrete ScratchFunction

Concrete ScratchValue = String,Int?,Float?,Bool?, (void/null?)


Selector -

ScratchFunction LeftArg RighArg -> ScratchValue

ScratchFuntion will Evaluate each Arg until it becomes a ScratchValue perform the function and return the ScratchValue

ScratchFunction => delegate ScratchBlock fn(ScratchObject this, ScratchBlock Args) // Type called fn with this function pattern

public ScratchBlock Subtract(ScratchObject this, ScratchBlock Args)
{
Assert Args.Count = 2;
ScratchValue leftARg = Eval Args 0
ScratchValue RightARg = Eval Arg 1

return new ScratchValue (leftArg - RightArg)
}

ScratchFunction
{

fn Invoke = Subtract;
}


BlockRunner to call SCratchBlocks => ScratchBlock only ever returns ScratchBlock or End?


ScratchValue

1/0 = (String)Infinity


Numeric operation on a string then take value of string as 0

boolean to string is true or false


Want a ScratchBlockFactory to make ScratchBlocks from Selector Names (Block Names)


Runner


Passed the first block in the script so has a ScratchBlock

(Note: Compiler check/optimisation only compile scripts that start with an event and are followed by at least one block.)


SCratchBlock needs to know the next block.


BlockRunner
{
ScratchBlock currentBlock;
ScratchObject this;
public void LoadScript(ScratchObject this, ScratchBlock start)
{
currentBlock = start;
this.this = this !
}
public ScratchBlock RunOneBlock()
{
if currentBlock is a ScratchFunction
return currentBlock = currentBlock.Invoke(this)
else
return currentBlock

}
public bool IsFinished()
{
return (currentBlock is a ScratchValue);
}
}

Let's have the this object as an interface call IScratchObject. This can the be implemented by the Stage, Sprites, clones etc.

Because we need to chain blocks then we need a script builder to go through the script and call block factory but remember the last block to then fix up the next block property of the previous block, do that in ScratchBlock

Which blocks wait for something to finish?
wait
glide
say for
think for
play sound until done
play drum for
rest for
play note for
broadcast and wait
ask and wait

Each IScratchObject will have a scheduler to schedule all its scripts. Wait type blocks need to remove their scripts from the scheduler until the event is complete then add back in.

What type of scripts are there (events)?
when green flag clicked
when key pressed
when sprite clicked
when backdrop switches
when loudness|timer|video motion >
when I receive
gtoal
Scratcher
1000+ posts

Scratch compiler beta test

Are you actually turning the Scratch statements into C# source code which you then compile, or are you just embedding a data structure representing the Scratch code in a program which interprets the Scratch statements from a C# executable? I thought I understood what you were doing but now I'm completely baffled :-)

If the former, I don't suppose you could show us a snippet of some translated Scratch code to let us see what it looks like in C#?

I'm interested in how you handle some of the major underlying translation issues, eg dynamic typing. Unless you do a very complex flow analysis (which *is* possible, because unlike other languages, with a Scratch program you're always guaranteed to have the complete source code available), you can't convert to int/float/string at compile time.

I guess with a language like C++ (and I presume C#?) where you have overloaded operators, you can *write* expressions like A = A - B but they'll always be implemented behind the scenes by a mess of code rather than a simple arithmetic operation.

G

Last edited by gtoal (Oct. 14, 2014 22:02:12)

procd
Scratcher
100+ posts

Scratch compiler beta test

When I started I wasn't sure how Scratch ran it's scripts. I thought it was a round robin approach taking a block from a script executing it then take the block from another script. I was also looking at F# at the time and liked the idea of a Scratchblock being a “value” or “function”. So the compiller is not converting to C# direct, so a forever block does not become for(;{ } as it does in your C compiler. In this a script is effectively a linked list of ScratchBlocks. A ScratchBlock is an abstract class with 2 concrete types

1) A ScratchValue which is my solution for Scratch's dynamic typing and this represents, floats, int, string, bool, null and converts between the types as needed

2) ScratchFn which is a function call to do some work.
gtoal
Scratcher
1000+ posts

Scratch compiler beta test

procd wrote:

When I started I wasn't sure how Scratch ran it's scripts. I thought it was a round robin approach taking a block from a script executing it then take the block from another script. I was also looking at F# at the time and liked the idea of a Scratchblock being a “value” or “function”. So the compiler is not converting to C# direct, so a forever block does not become for ( ; ; ) { } as it does in your C compiler. In this a script is effectively a linked list of ScratchBlocks. A ScratchBlock is an abstract class with 2 concrete types

Gotcha. I would call that an interpreter or VM rather than a compiler, but the name is not really important. The end result is similar. So are you saying that your multitasking is done by coroutines that you're explicitly manually scheduling yourself, rather than using C's pthreads or whatever C#'s lightweight threads are called?

G
procd
Scratcher
100+ posts

Scratch compiler beta test

Correct. Yes compiler is potentially misleading, but for want of a better name ;-) besides it still has to compile everything to CIL and package everything into an exe.
Yes I use my own scheduler as that seemed the best way at the time. Because I thought the blocks were run round robin then if separate threads had to yield after each statement then it would be horribly inefficient. Now I know that not to be the case then perhaps I would've done things differently. It was all an exploration of what was possible at the time. I based the graphics side on monogame and the audio on naudio, both of which I'd never used before so that was an adventure too. Certainly learnt a lot about Scratch and although not perfect, pleased with the end result.
procd
Scratcher
100+ posts

Scratch compiler beta test

So
(() + ())
becomes
       public static ScratchBlock AddFn(IScratchThread st, ScratchBlock[] args)
{
ScratchValue l, r;
if (args[0] is ScratchFunction)
{
l = (new BlockRunner(st, args[0])).EvaluateBlock();
}
else
{
l = (ScratchValue)args[0];
}
if (args[1] is ScratchFunction)
{
r = (new BlockRunner(st, args[1])).EvaluateBlock();
}
else
{
r = (ScratchValue)args[1];
}
l = l.BestNumberFormat(l);
r = l.CastToCompatibleBlock(r);
if (l.GetScratchValueType() != r.GetScratchValueType())
{
// probably need to upconvert an int to a double to avoid overflows
l = r.CastToCompatibleBlock(l);
}
switch (l.GetScratchValueType())
{
case ScratchValue.ScratchValueType.ValueInt:
try
{
checked
{
return new ScratchValue(l.ToInt() + r.ToInt());
}
}
catch (OverflowException)
{
return new ScratchValue(l.ToDouble() + r.ToDouble());
}
case ScratchValue.ScratchValueType.ValueDouble:
return new ScratchValue(l.ToDouble() + r.ToDouble());
default:
throw new BlockException("Unexpected non-numeric Block Type");
}
}

Last edited by procd (Oct. 15, 2014 08:56:40)

s_federici
Scratcher
500+ posts

Scratch compiler beta test

Hi, any news about when the source code will be released?
__init__
Scratcher
1000+ posts

Scratch compiler beta test

procd wrote:

So
(() + ())
becomes
       public static ScratchBlock AddFn(IScratchThread st, ScratchBlock[] args)
{
ScratchValue l, r;
if (args[0] is ScratchFunction)
{
l = (new BlockRunner(st, args[0])).EvaluateBlock();
}
else
{
l = (ScratchValue)args[0];
}
if (args[1] is ScratchFunction)
{
r = (new BlockRunner(st, args[1])).EvaluateBlock();
}
else
{
r = (ScratchValue)args[1];
}
l = l.BestNumberFormat(l);
r = l.CastToCompatibleBlock(r);
if (l.GetScratchValueType() != r.GetScratchValueType())
{
// probably need to upconvert an int to a double to avoid overflows
l = r.CastToCompatibleBlock(l);
}
switch (l.GetScratchValueType())
{
case ScratchValue.ScratchValueType.ValueInt:
try
{
checked
{
return new ScratchValue(l.ToInt() + r.ToInt());
}
}
catch (OverflowException)
{
return new ScratchValue(l.ToDouble() + r.ToDouble());
}
case ScratchValue.ScratchValueType.ValueDouble:
return new ScratchValue(l.ToDouble() + r.ToDouble());
default:
throw new BlockException("Unexpected non-numeric Block Type");
}
}
Well, not exactly…
function(b:*):* { return interp.numarg(b, 0) + interp.numarg(b, 1) };

Edit: Oh wait, interp.numarg() is
public function numarg(b:Block, i:int):Number {
		var args:Array = b.args;
		if (b.rightToLeft) { i = args.length - i - 1; }
		var n:Number = (args[i] is BlockArg) ?
			Number(BlockArg(args[i]).argValue) : Number(evalCmd(Block(args[i])));
		if (n != n) return 0; // return 0 if NaN (uses fast, inline test for NaN)
		return n;
	}
I guess AS is more efficient than CS…

Last edited by __init__ (Nov. 7, 2014 22:15:29)


thisandagain pls explain
procd
Scratcher
100+ posts

Scratch compiler beta test

SimpleScratch
Scratcher
500+ posts

Scratch compiler beta test

Brilliant - worked first time

Simon
procd
Scratcher
100+ posts

Scratch compiler beta test

SimpleScratch wrote:

Brilliant - worked first time

Simon
Thanks. FYI The compiler also supports http extensions.
__init__
Scratcher
1000+ posts

Scratch compiler beta test

Microsoft Windows [Version 6.3.9600]
(c) 2013 Microsoft Corporation. All rights reserved.

C:\Users\David\Documents\procd>procd -o=test.exe "F:\FOLDER03 [scratch]\Invisible.sb2"
Procd version 1.0.0.0
2014-11-25 19:03:22.0656 procd.ScratchCompiler.Compile Error *** 50 Parsing Problems encountered. ***
2014-11-25 19:03:31.3346 procd.ScratchCompiler.Compile Error Line number 8, Error Number: CS1009, 'Unrecognized escape sequence;
2014-11-25 19:03:31.3346 procd.ScratchCompiler.Compile Error Line number 8, Error Number: CS1009, 'Unrecognized escape sequence;
2014-11-25 19:03:31.8578 procd.Program.Main Fatal Compiler Errors Compiler Errors

C:\Users\David\Documents\procd>

thisandagain pls explain
procd
Scratcher
100+ posts

Scratch compiler beta test

__init__ wrote:

Microsoft Windows [Version 6.3.9600]
(c) 2013 Microsoft Corporation. All rights reserved.

C:\Users\David\Documents\procd>procd -o=test.exe "F:\FOLDER03 [scratch]\Invisible.sb2"
Procd version 1.0.0.0
2014-11-25 19:03:22.0656 procd.ScratchCompiler.Compile Error *** 50 Parsing Problems encountered. ***
2014-11-25 19:03:31.3346 procd.ScratchCompiler.Compile Error Line number 8, Error Number: CS1009, 'Unrecognized escape sequence;
2014-11-25 19:03:31.3346 procd.ScratchCompiler.Compile Error Line number 8, Error Number: CS1009, 'Unrecognized escape sequence;
2014-11-25 19:03:31.8578 procd.Program.Main Fatal Compiler Errors Compiler Errors

C:\Users\David\Documents\procd>
If you send a link to the project then I'll taka look. Guess that there's some odd characters in your project. Possibly as a variable name or in a custom block?
goldfish678
Scratcher
1000+ posts

Scratch compiler beta test

__init__ wrote:

Microsoft Windows [Version 6.3.9600]
(c) 2013 Microsoft Corporation. All rights reserved.

C:\Users\David\Documents\procd>procd -o=test.exe "F:\FOLDER03 [scratch]\Invisible.sb2"
Procd version 1.0.0.0
2014-11-25 19:03:22.0656 procd.ScratchCompiler.Compile Error *** 50 Parsing Problems encountered. ***
2014-11-25 19:03:31.3346 procd.ScratchCompiler.Compile Error Line number 8, Error Number: CS1009, 'Unrecognized escape sequence;
2014-11-25 19:03:31.3346 procd.ScratchCompiler.Compile Error Line number 8, Error Number: CS1009, 'Unrecognized escape sequence;
2014-11-25 19:03:31.8578 procd.Program.Main Fatal Compiler Errors Compiler Errors

C:\Users\David\Documents\procd>
How do you copy that? I have an error code I've been wanting to report to Procd, but I can't figure out how to copy it. Ignore

Last edited by goldfish678 (Nov. 26, 2014 13:45:53)

goldfish678
Scratcher
1000+ posts

Scratch compiler beta test

Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.

C:\Users\NAMEEDITEDOUT>cd Documents\Scratch 2.0 Projects

C:\Users\NAMEEDITEDOUT\Documents\Scratch 2.0 Projects>procd -o="It's June!.exe" "It's J
une!.sb2"

Unhandled Exception: System.TypeInitializationException: The type initializer fo
r 'procd.Program' threw an exception. ---> System.IO.FileNotFoundException: Coul
d not load file or assembly 'NLog, Version=2.0.1.0, Culture=neutral, PublicKeyTo
ken=5120e14c03d0593c' or one of its dependencies. The system cannot find the fil
e specified.
at procd.Program..cctor()
--- End of inner exception stack trace ---
at procd.Program.Main(String[] args)

Last edited by goldfish678 (Nov. 26, 2014 13:48:31)

procd
Scratcher
100+ posts

Scratch compiler beta test

goldfish678 wrote:

Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.

C:\Users\NAMEEDITEDOUT>cd Documents\Scratch 2.0 Projects

C:\Users\NAMEEDITEDOUT\Documents\Scratch 2.0 Projects>procd -o="It's June!.exe" "It's J
une!.sb2"

Unhandled Exception: System.TypeInitializationException: The type initializer fo
r 'procd.Program' threw an exception. ---> System.IO.FileNotFoundException: Coul
d not load file or assembly 'NLog, Version=2.0.1.0, Culture=neutral, PublicKeyTo
ken=5120e14c03d0593c' or one of its dependencies. The system cannot find the fil
e specified.
at procd.Program..cctor()
--- End of inner exception stack trace ---
at procd.Program.Main(String[] args)
Have you extracted the nlog.dll from the zip file to the same folder as procd.exe? (Extract all the files from the zip file to the same directory)

Powered by DjangoBB