HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Utilizing higher objects (Jass->C#)

04-27-2007, 11:08 PM#1
Mapz_Maker
I am building a compiler for jass to be used on windows. It is a pitzermike called it "a pattern-matching" compiler. Some say this is not the best thing. The integrated development environment will most likely soon have its own syntax checker. When i am pattern-matching away there is a problem. Since the compiler is not built for Jass but for AOOJass (a similar language that i am designing) it needs to be able to support classes. The way i pattern match is having a problem. It seems to do the following conversion.

Code:
class MyClass
private:
function myfunc takes nothing returns nothing
attempt myfunc2()
endfunction
public:
function myfunc2 takes nothing returns nothing
endfunction
endclass

-->

Code:
class MyClass
{
//This code was originally in JASS
//The code created by the JASS Compiler is in C#
public static string I2S(int i)
{
return i.ToString();
}
public static int R2I(float f)
{
return (int)f;
}
public static float I2R(int i)
{
return (float)i;
}
public static string R2S(float f)
{
return f.ToString();
}
public static float S2R(string s)
{
return Convert.ToDecimal(s);
}
 static void Main()
{
string environvars034834028 = Environment.GetCommandLineArgs()[0]; //these two lines are for if you have option: enable logs
environvars034834028[0] = environvars034834028[0].Substring(0, environvars034834028[0].LastIndexOf("\\")) + "errorlog.txt";
}


private static void myfunc()
{

try {myfunc2();} catch {} //the result of the attempt attribute when option: enable logs is off
}



public static void myfunc2()
{
}
//Need a } here, but how do i get it?

i'm not yet posting the source for the compiler since i feel i am close to a conclusion, yet am still unsure. If you know how this would be done in a pattern matching compiler (this only converts it to C#, not an exe, though ms was kind enough to include csc.exe on all .net framework installed computers :D [C:\Windows\Microsoft.Net\YourLatestUpdateVersion\csc.exe, just google using csc.exe and look for microsoft's page which describes it very well] which can compile into winexe/consoleexe/and library) then please post here

the compiler works in three methods

the first method analyzes the command line args, then call the second method

the second method divides the code up into functions and headers, it also identifies that you do not place a function within a function. It additionally divides the function headers up. (parameters, returnval, funcname, funcsecurity)

the third method recollects the information from where it was stored after the second method finished. It then formats the code into C#.

so how would i know where the end of a method is? the header is all the material not in functions As one string.
04-28-2007, 01:11 AM#2
BlacKDicK
I can help you, but first I need to understand what is going on.
You´re writing a command line tool (in C#) to convert Jass code to C# code right? The tool works as follows: "jass2csharp original.jass converted.cs"

I tried to understand it, but I got confused. This tool takes ANY jass code or it only works with blizzard.j . I mean, blizzard.j has some natives and since you can´t convert natives (like I2S), you´re writing your own "natives" directly in C#.

I got lost when you tried to explain the methods. What do you want to do and what is the problem you´re facing? Where are those "headers" you´re talking about?
04-28-2007, 03:39 AM#3
Mapz_Maker
>>>You´re writing a command line tool (in C#) to convert Jass code to C# code right?
correct And i have nearly finished a development environment for AOOJass (Attributes and Objects Oriented Jass)
>>>The tool works as follows: "jass2csharp original.jass converted.cs"
basically, except it is "Jass Compiler.exe original.j [background] [compile pathofcsharpfiles]
background is optional (which is why i, for this example, put it in brackets) as is compile. compile requires an additional arguement for the location of one or more .cs files. it compiles them into a binary with a wildcard so you only put in one location.
>>>This tool takes ANY jass code or it only works with blizzard.j
it works with any code that has a base (an example of not having a base would be the natives in war3, how is windows supposed to kindly ask blizzard for the actions? ), and is .net. if you gave it code out of blizzard.j that was formatted correctly and did not reference to natives, it would work. btw, the proper formatting for AOOJass is

securitylevel(public, private, default):
function funcname takes funcparams returns vartype
call/attempt/set/return CODE //(call can only be used for calling a method, set for setting a variable and attempt for either, return is special)
endfunction

example

public:
function myfunction takes integer i returns integer
call donothing()
attempt dosomething()
attempt i = i + 4
set i = i + 4
return i
endfunction

>>>I got lost when you tried to explain the methods. What do you want to do and what is the problem you´re facing? >>>Where are those "headers" you´re talking about?

long story short: when i use a class, the class gets placed into the 'header' during the second method (which finds the data) but then in the third method (which formats the data for C#) i need a way to make functions be placed in their respective classes and the classes need to close themselves ('}').

btw, their are actually four methods the first is the commandlineargs interpreter and the fourth writes to files and does compiliation into a binary (if you choose to do so and is possible)

Ok, what i meant by the 'header' was literally anything not in a method so for example

//header
class myclass //in the header
//nonheader
function myfunc takes nothing returns nothing //not in the header
call somethingelse() //not in the header
endfunction //not in the header
//header
endclass //in the header

in the example i removed the security statement ('private: in the earlier example) because it becomes embedded in variables before we run into the problem stage.

i use a string for passing the header from the second method to the third method and a struct for passing the functions from the second method to the third. here is the struct

Code:
        struct JFunction //Jass Function
        {
            public string funcname;
            public string[] parameters;
            public string returnval;
            public string funcsecurity;
            public string funcbody;
        }

btw, thanks for replying so fast.
04-28-2007, 01:26 PM#4
PitzerMike
I don't really get the problem.
If the } is not there, why don't you simply write it with a WriteLine statement?
Your problem description seems a bit vague.
04-28-2007, 01:45 PM#5
Vexorian
Hi mapz-maker, I must say this.

You are writing a compiler! Please notice how much you need to get a long with regular languages, regular expressions and context-free grammars. I am almost sure there are compiler generators for .NET out there, use them.
04-28-2007, 03:07 PM#6
BlacKDicK
Mapz_Maker, as Vex said, you´re trying to write a compiler. Although you made some things more clear, I still don´t get where is your problem. Anyway, I just wrote a C# class that might help you somehow on your journey. Get the attached file and see if it helps you.

Btw, writing a compiler is somehow complicated. Syntax parsing is not an easy task, you should get familiar with regular expressions to parse syntax (I still lack better understanding of it) and use Reflection to write code. Juts google for "C# regular expressions" and "c# code compile" and you will find some material.

Anyway, I wrote the class in a hurry, so lots of proper parsing are missing and maybe incorrect. For testing purposes, it converted the following jass code into csharp code:
Code:
class MyClass
private:
function myfunc takes nothing returns nothing
attempt myfunc2()
endfunction
private:
function Multiply takes integer a, integer b returns integer
return a * b
endfunction
public:
function myfunc2 takes nothing returns nothing
endfunction
endclass

Code:
// Generated by AOOJassCompiler.

using System;

namespace Jass
{
	using nothing = System.Void;
	using boolean = System.Boolean;
	using integer = System.Int32;
	using real = System.Single;
	using handle = System.Object;

	class MyClass
	{
		nothing myfunc ()
		{
			// Original JassCode
			// attempt myfunc2()
		}

		integer Multiply (integer a, integer b)
		{
			// Original JassCode
			// return a * b
			return 0;
		}

		public nothing myfunc2 ()
		{
			// Original JassCode
		}

	} // class MyClass
} //namespace Jass
Attached Files
File type: zipJassCompiler.zip (1.7 KB)
04-28-2007, 04:01 PM#7
PitzerMike
I already voiced my opinion in the other thread at wc3jass.com
but I'll say it again. A compiler based on pattern matching isn't going to cut it.

I'd use a compiler generator (Coco/R for .net) and CodeDom to generate the C# code. CodeDom is a nice API (included in standard .net) to generate .NET source code, translate it to IL code and load it at runtime. This means you can skip the step where you manually have to translate the C# code with csc.

Alternatively/additionally you could use Reflection.Emit to create/modify your classes on the IL code level. The .net instruction set is simple enough.
04-28-2007, 06:37 PM#8
Mapz_Maker
thanks pitzer for revoicing your opinion... but i do believe mine is doing the task except for the classes (and i guess, namespaces). I must commend you BlackDick for your code, it appears a lot cleaner than mine but does a pretty good job.

edit: i looked into system.reflection.emit and it appears i could write a stand-alone compiler very easily, if not as quickly as i built the one i currently have! [edit2: yet again, microsoft fails horribly. emit uses IL]

i am currently using the writeline("}") method but it is temporary as it limits me to one class per file.

and how do you color text in a richtextbox with out selecting the text? because i have to select the text with code, it is very slow at highlighting keywords/etc. i know there is a better way. How?