• Tidak ada hasil yang ditemukan

BAB III PERANCANGAN. Karakter-karakter yang diijinkan dipakai dalam bahasa DOGI adalah

N/A
N/A
Protected

Academic year: 2021

Membagikan "BAB III PERANCANGAN. Karakter-karakter yang diijinkan dipakai dalam bahasa DOGI adalah"

Copied!
47
0
0

Teks penuh

(1)

BAB III

PERANCANGAN

3.1 Spesifikasi bahasa DOGI

3.1.1 Token

Karakter-karakter yang diijinkan dipakai dalam bahasa DOGI adalah sembarang karakter selain karakter kontrol, dalam set karakter ASCII. DOGI tidak mendukung penggunaan karakter-karakter unicode. Carriage return, line feed, dan tab dianggap sebagai white space. Frasa “sembarang karakter” yang digunakan selanjutnya akan selalu berarti “sembarang karakter dalam set karakter yang diijinkan bahasa DOGI”.

A. Kata kunci

Kata-kata kunci yang digunakan oleh DOGI adalah:

package imports exports class access interface method property hidden

(2)

visible get set new kill begin end B. Pengenal (identifier)

Pengenal (identifier) dalam bahasa DOGI dimulai dengan huruf atau garis bawah atau @. Setiap karakter selanjutnya bisa merupakan salah satu dari huruf, garisbawah, @ maupun angka, tidak dibatasi panjangnya. Pengenal dalam bahasa DOGI tidak membedakan huruf besar maupun kecil (bersifat case-insensitive).

Contoh nama-nama pengenal:

dogi anjing si_manis @anak_dogi_1 bopi@home C. Literal

Literal merepresentasikan data. Bahasa DOGI mengenal tujuh macam literal, yaitu null, integer, floating-point, string, boolean, array dan code.

Null

Literal null tidak merepresentasikan data secara konkret. Null digunakan untuk menandai bahwa suatu nama tidak mereferensikan objek apa pun, walaupun itu

(3)

berarti nama tersebut mereferensikan sebuah objek – yaitu objek null sendiri. Null merupakan instansiasi dari kelas void. Dituliskan sebagai #null.

Integer

Literal integer merupakan representasi dari bilangan bulat. Literal integer sendiri terdiri dari dua macam representasi, yaitu desimal dan heksadesimal. Literal desimal terdiri dari barisan angka-angka yang panjangnya tidak dibatasi (walaupun aturan semantik akan membatasi nilainya, yang tergantung pada arsitektur komputer saat ini). Literal heksadesimal diawali dengan 0x, dilanjutkan dengan barisan angka maupun salah satu huruf a sampai f tanpa dibedakan huruf besar maupun kecil. Literal integer merupakan instansiasi dari kelas int. Graf sintaks untuk digit desimal, digit heksadesimal, dan literal integer dapat dilihat pada Gambar 3.1, Gambar 3.2, dan Gambar 3.3.

digit 0 1 2 3 4 5 6 7 8 9

(4)

hexdigi t digit A F E D C B

Gambar 3.2 Graf sintaks untuk digit heksadesimal

integer digit

hexdigit

0 x

Gambar 3.3 Graf sintaks untuk literal integer

Contoh-contoh literal integer:

2152332

3154258763248678 0x42AB38C

0x32cFf

Floating-point

Literal floating-point merupakan representasi dari bilangan real, dan instansiasi dari kelas real. Literal floating-point terdiri dari beberapa bagian, yaitu bagian integer, titik desimal, bagian pecahan dan eksponen.

Pembentukan literal floating-point yang valid adalah

(5)

• Eksponen diawali huruf E atau e, diikuti langsung dengan angka-angka, atau bisa juga dengan plus atau minus, diikuti angka-angka.

• Bagian integer diikuti langsung dengan eksponen, atau

• Bagian integer diikuti dengan titik desimal, bagian pecahan, dan bisa diikuti oleh eksponen maupun tidak.

Graf sintaks untuk literal floating-point dapat dilihat pada Gambar 3.4.

Floating-point . E

+

-digit digit digit

Gambar 3.4 Graf sintaks untuk literal floating-point

Contoh-contoh literal floating-point:

124.12525 3.2 0.52e23 325.253e-004 5321124.4e+2 String

Literal string adalah barisan sembarang karakter (kecuali tanda kutip ganda), di antara dua tanda kutip ganda (“). Backslash (\) digunakan sebagai karakter escape, untuk menyatakan karakter kontrol ataupun karakter lainnya. Literal string merupakan instansiasi dari kelas string. Graf sintaks untuk karakter tunggal, karakter, dan string dapat dilihat pada Gambar 3.5, Gambar 3.6, Gambar 3.7, sedangkan daftar karakter escape dapat dilihat pada Tabel 3.1.

(6)

\b Backspace \t Tabulasi \n line feed \f Form feed \r carriage return \” kutip ganda \\ Backslash

\m## mengulang karakter sebelumnya sebanyak ## \u#### karakter unicode nomor ####

\0x## karakter ASCII nomor ##

Tabel 3.1 Karakter-karakter escape yang berlaku

Contoh-contoh literal string:

“Aku gigi mulut rumahku”

“ \”Aku gigi mulut rumahku\” adalah string” “Aku\ngigi\nmulut\nrumahku\0x0D”

(7)

singlechar ! A ~ 0 9 Z a z ... ... ... ... ... ... ...

Gambar 3.5 Graf sintaks untuk karakter tunggal

singlechar m u hexdigit hexdigit 0 x Char \ singlechar

hexdigit hexdigit hexdigit hexdigit

Gambar 3.6 Graf sintaks untuk karakter

String

char

Gambar 3.7 Graf sintaks untuk literal string

Boolean

Literal boolean hanya ada dua, yaitu #true dan #false. Sesuai namanya, #true menunjukkan nilai benar, dan #false menunjukkan nilai salah. Kedua

(8)

literal ini merupakan instansiasi dari kelas bool. Pemberian tanda # mempermudah pembedaan dari nama objek.

Array

Literal array merepresentasikan array, dan merupakan instansiasi dari kelas array. Literal array dituliskan sebagai daftar yang dipisahkan tanda koma, dan dituliskan di antara tanda kurung kurawal. Graf sintaks untuk array dapat dilihat pada Gambar 3.8.

expr

array { }

,

Gambar 3.8 Graf sintaks untuk literal array Contoh-contoh literal array:

{ 5, 2, 9, 4, 3, 2 }

{ console.writeln(3), Count()+2, 2+4*con_9, #false } { [ 5-f ], #true, { 5, 4, { 3, 2 }, 4 }, “abcde” }

Code

Dalam bahasa DOGI terdapat tambahan literal yang lain, yaitu kode (code). Sifatnya seperti block pada SmallTalk. Literal kode yang dituliskan dalam sebuah metoda tidak akan dieksekusi, melainkan dianggap sebagai objek instansiasi dari kelas code. Penulisannya selalu berada di antara kata begin..end untuk kode dengan nol atau lebih statement, dan di antara [ .. ] untuk kode dengan nol atau satu statement. Kode tidak secara otomatis dieksekusi. Graf sintaks untuk kode dapat dilihat pada Gambar 3.9.

(9)

code begin end [ ] exprList expr exprList expr ;

Gambar 3.9 Graf sintaks untuk literal code

Contoh-contoh berikut adalah literal code: begin dogi makan; end

begin out.write(“Guk!”); end D. Pemisah

Pemisah (separator) digunakan untuk memisahkan token-token. Daftar lengkap pemisah yang digunakan dapat dilihat pada Tabel 3.2 berikut.

( Berpasangan dengan ), digunakan untuk mengawali daftar parameter sebuah metoda, atau untuk memberikan presedensi bagi ekspresi

) Merupakan penutup bagi (

{ Berpasangan dengan }, digunakan untuk mengawali suatu literal array } Merupakan penutup bagi {

[ Berpasangan dengan ], digunakan untuk indexer (dicadangkan), maupun code dengan satu ekspresi

] Merupakan penutup bagi [ (dicadangkan)

(10)

dalam sebuah method. < juga digunakan sebagai operator. > Merupakan penutup bagi <, juga digunakan sebagai operator. ; Digunakan untuk memisahkan bagian-bagian dalam program DOGI , Pemisah dalam daftar

. Titik desimal, juga digunakan sebagai qualifier bagi objek

Tabel 3.2 Pemisah dalam bahasa DOGI

E. Operator

Operator adalah metoda. Operator tidak mendapat perlakuan khusus seperti pada bahasa-bahasa pemrograman lainnya. Operator hanyalah metoda yang diberi nama dengan simbol-simbol tertentu. Operator dibentuk dari satu atau sepasang simbol-simbol berikut dan masing-masing tidak didefinisikan.

= < > + - * / ! & | % ^ : ? \

Pasangan operator /* dan */ tidak dapat dipakai karena sudah dipakai sebagai tanda awal dan akhir komentar.

Contoh operator:

+ = += <<

(11)

F. White space

Karakter-karakter yang termasuk white space adalah spasi, tabulasi, new line, carriage return, dan line feed. Karakter-karakter tersebut diabaikan dalam proses kompilasi.

G. Komentar

Komentar dalam DOGI sama dengan yang dipakai pada bahasa C++. Ada dua jenis komentar, yaitu komentar satu baris, dan komentar bersarang (nested comment). Komentar satu baris diawali dengan tanda //, dan karakter-karakter berikutnya merupakan komentar sampai baris tersebut berakhir. Komentar bersarang diawali tanda /* dan diakhiri dengan */, tidak harus dituliskan dalam baris yang sama. Graf sintaks untuk komentar dapat dilihat pada Gambar 3.10.

c o m m e n t / * * /

/ /

a n y c h a r a c t e r

s i n g l e c h a r

Gambar 3.10 Graf sintaks untuk komentar

Contoh komentar bersarang:

/* Komentar komentar komentar komentar komentar komentar komentar komentar komentar komentar komentar komentar */

Contoh komentar satu baris:

(12)

3.1.2 Struktur program

Suatu program dalam bahasa DOGI dibentuk oleh daftar kelas, antarmuka kelas, dan antarmuka. Masing-masing deklarasi dipisahkan oleh tanda titik koma (;). Deklarasi-deklarasi tersebut disatukan dalam package, yang dituliskan dalam sebuah file kode sumber. Sebuah file kode sumber DOGI dapat memiliki lebih dari sebuah package. Graf sintaks untuk kode sumber dalam bahasa DOGI dapat dilihat pada Gambar 3.11.

source package ;

Gambar 3.11 Graf sintaks untuk file program dalam bahasa DOGI

3.1.3 Package

Package adalah satuan paling kecil yang dapat dikompilasi secara mandiri. Sebuah package berisi daftar kelas, antarmuka kelas, dan antarmuka. Dituliskan dengan bentuk:

package <nama_package> begin <daftar_deklarasi> end;

Sebuah package dapat mengimpor antarmuka-antarmuka kelas dari package lain dengan menuliskan dalam daftar deklarasi:

imports <nama_package> . <nama_simbol> { ,

<nama_package> . <nama_simbol> } ;

Penulisan <nama_package>.* akan mengimpor semua nama yang diekspor oleh package yang dimaksud. Simbol-simbol yang dapat diimpor haruslah telah diekspor pada package yang bersangkutan, dengan menyebutkan:

(13)

exports <nama_simbol> { , <nama_simbol> } ;

Hanya antarmuka kelas (ditandai dengan kata kunci access) dan antarmuka (interface) yang dapat diekspor dan diimpor oleh sebuah package. Package tanpa nama adalah package yang tidak dapat diimpor oleh kelas manapun. Package tanpa nama adalah untuk package yang berisi program siap eksekusi, sehingga tidak perlu diimpor oleh kelas manapun. Kompiler DOGI untuk saat ini hanya mendukung satu package dalam sebuah file.

Graf sintaks untuk package dapat dilihat pada Gambar 3.12.

packageHeader package packageName

package packageHeader begin packageItems end

packageItems packageItem ; imports exports access interface class packageItem

(14)

3.1.4 Kelas

A. Deklarasi kelas

Sebuah kelas dideklarasikan menggunakan kata kunci class, diikuti nama kelas induk, diikuti nama kelas yang akan dibuat. Bagian ini dinamakan class declaration header, dan sudah cukup untuk mendeklarasikan sebuah kelas.

class <nama_akses> <nama_kelas> [ ( [ <nama_interface>

{ , <nama_interface> }] ) ]

Kelas yang dihasilkan dengan cara ini akan memiliki sifat sama persis dengan kelas induknya, yang memiliki visibilitas <nama_akses>. Modifikasi terhadap anggota-anggota kelas dapat dituliskan setelah declaration header, diawali kata begin dan diakhiri kata end.

<class_header> begin <daftar_anggota_kelas> end;

Graf sintaks untuk kelas dapat dilihat pada Gambar 3.13. Contoh deklarasi kelas:

class binatang anjing

// anggota-anggota kelas di sini …

(15)

classMember

property field method

class baseAccessName className

classHeader ( interfaceList )

interfaceList interfaceName ,

class classHeader begin classMember ; end

Gambar 3.13 Graf sintaks untuk class

B. Anggota-anggota kelas

Sebuah kelas memiliki lima macam anggota (class member) yaitu: • Field,

• Metoda (method),

• Konstruktor, yaitu metoda khusus yang bertugas untuk menciptakan instance.

• Destruktor, yaitu metoda khusus untuk menghapus instance yang sudah dibuat.

• Properti, yaitu antarmuka terhadap field/metoda dengan memperlakukannya sebagai nama objek.

(16)

C. Field

Field dideklarasikan dengan bentuk umum

[ field ] <nama_kelas> [*] <nama_field> { , [*] <nama_field> }

Penggunaan kata kunci field adalah optional. Tanda * dipakai sebagai tanda bahwa field yang bersangkutan tidak secara otomatis dialokasikan (dengan memanggil metoda new dari field yang bersangkutan), melainkan menunjuk pada #null.

Graf sintaksnya seperti pada Gambar 3.14.

field accessName fieldName

,

field *

Gambar 3.14 Graf sintaks untuk field

Contoh:

int umur; anjing * dogi;

field kucing si_manis, * si_putih; D. Metoda

Deklarasi metoda memiliki dua bagian, yaitu method signature dan kode. Method signature berupa nama kelas, diikuti nama metoda, diikuti daftar parameter yang dituliskan di antara tanda kurung.

<nama_kelas_hasil> <nama_metoda>

(17)

Deklarasinya berupa kata kunci method diikuti method signature. Jika diikuti dengan kode program, artinya metoda tersebut langsung diimplementasikan dalam kode-kode di dalamnya. Jika tidak, metoda tersebut dianggap sebagai metoda abstrak dan tidak boleh dipanggil sebelum diimplementasikan dalam kelas turunannya.

Kode program dituliskan di antara kata kunci begin dan end seperti pada bahasa Pascal. Objek-objek lokal dapat dituliskan di antara signature dan kodenya, diapit tanda < dan >.

method <method_signature>

[ < <nama_kelas> <nama_objek_lokal> , … > ]

begin <kode> end;

Selain dengan cara menuliskan barisan kode-kodenya, DOGI memiliki alternatif penulisan definisi metoda dengan menuliskan ekspresinya secara langsung, jika kode hanya terdiri dari sebuah ekspresi saja.

method <method_signature> [ < <nama_kelas>

<nama_objek_lokal> , … > ] = <ekspresi> ;

Dengan menambahkan titik pada nama metoda, metoda tersebut akan dianggap sebagai class method atau static method, yaitu metoda yang dikaitkan dengan nama kelas. Class method tidak dapat mengakses field yang dideklarasikan dalam kelas yang bersangkutan. Graf sintaks untuk metoda dapat dilihat pada Gambar 3.15.

(18)

accessName

methodSignature methodName ( declArgList )

. .new

kill ( )

declArgList accessName argName

,

method method methodSignature < localList >

begin exprList end = expr

localList accessName localName

,

;

Gambar 3.15 Graf sintaks untuk metoda

Contoh:

method int jumlah (int a, int b) < int hasil >

begin

hasil = a + b; return (hasil);

end;

method real kuadrat (int x) = x * x;

(19)

E. Konstruktor

Konstruktor adalah metoda khusus, berguna untuk menginstansiasikan sebuah kelas. Karena konstruktor adalah class method, maka nama konstruktor harus diawali titik. Konstruktor diijinkan untuk lebih dari satu dalam satu kelas, dibedakan berdasarkan signature-nya. Untuk field yang dialokasikan secara otomatis (tidak diberi tanda *), konstruktor akan mengalokasikan field tersebut dengan konstruktor .new() yang terdapat pada field tersebut. Graf sintaks untuk konstruktor dapat dilihat pada Gambar 3.15.

method .new ( [ <nama_kelas_parameter>

<nama_parameter> , … ] ) Contoh: method .new () begin end;

method .new (int A) begin

end;

F. Destruktor

Berbeda dengan konstruktor, destruktor hanya diijinkan satu untuk setiap kelas, dan tidak menggunakan parameter. Destruktor digunakan untuk menghapus objek. Karena destruktor bukanlah class method, maka penamaannya tidak diawali tanda titik. Graf sintaks untuk destruktor dapat dilihat pada Gambar 3.15.

(20)

method kill ( ) Contoh: method kill() begin end; G. Properti

Properti sebenarnya adalah penyingkatan dari penggunaan dua buah metoda yang berlaku sebagai getter (pengambil nilai) dan setter (pengeset nilai), disingkat penulisannya menjadi sebuah nama yang diperlakukan sebagai objek tunggal.

Properti dapat dideklarasikan menggunakan salah satu dari penulisan ini:

property <nama_akses> <nama_properti> = <nama_field> property <nama_akses> <nama_properti> [ get begin

<definisi_get> end ] [ set begin <definisi_set>

end]

property <nama_akses> <nama_properti> [ get =

<definisi_get> ] [ set = <definisi_set> ]

Graf sintaks untuk properti dapat dilihat pada Gambar 3.16. Contoh:

property int Count=fCount;

property TColor Color get = fColor set begin

fColor = Color; return (fColor);

(21)

getter get propertyDef

setter set propertyDef

propertyDef

expr

=

begin exprList end

< localList >

property property propertySignature

getter setter

getter setter

= fieldName

propertySignature accessName propertyName

Gambar 3.16 Graf sintaks untuk properti

H. Akses (access) atau antarmuka kelas (class interface)

Antarmuka kelas (class interface) atau disebut akses merupakan hal yang tidak terdapat dalam bahasa pemrograman OOP lainnya. Antarmuka kelas secara esensial merupakan visibilitas dari anggota-anggota kelas. Setiap anggota kelas yang didaftar dalam deklarasi class secara default memiliki visibilitas private, atau tidak dapat diakses oleh objek lain maupun kelas turunannya.

Setiap anggota kelas yang didaftar dalam antarmuka kelas secara default memiliki visibilitas public. Visibilitas public juga dapat diperoleh dengan memberi awalan visible. Jika diberi awalan hidden, artinya anggota kelas yang

(22)

bersangkutan memiliki visibilitas protected. Selain yang didaftar dalam antarmuka kelas, anggota kelas bersifat private.

Anggota-anggota yang dapat didaftar dalam antarmuka kelas hanya metoda dan properti saja (termasuk konstruktor dan destruktor). Field tidak dapat, untuk menjaga objek dari perubahan-perubahan yang tak terkendali.

Setiap anggota yang hendak di-publish didaftarkan signature-nya tepat seperti yang telah didaftarkan di deklarasi kelasnya. Hanya saja tidak ada ketentuan bahwa nama parameter harus sama persis dengan yang telah dituliskan dalam deklarasi kelas.

Antarmuka kelas atau akses dituliskan dengan header:

access <nama_kelas> [ <nama_antarmuka_kelas> ]

Sebuah kelas dapat memiliki lebih dari satu antarmuka. Jika nama antarmuka kelas tidak disebutkan, atau bahkan antarmuka untuk sebuah kelas tidak dibuat, dianggap antarmuka untuk kelas tersebut sama dengan nama kelasnya. Untuk setiap kelas selalu terdapat satu antarmuka yang namanya sama dengan nama kelasnya.

Untuk menurunkan sebuah kelas dari kelas lain, harus menyebutkan nama antarmukanya, dan bukan nama kelasnya. Anggota-anggota base class yang dapat diakses hanyalah yang disebutkan dalam antarmuka base class yang dipakai. Dengan demikian suatu kelas dapat memiliki banyak ‘muka’ untuk berhubungan dengan kelas lainnya.

Hal ini berguna salah satunya untuk menghemat jumlah kelas yang harus dibuat. Dalam VCL Delphi, untuk setiap komponen kontrol biasanya terdapat

(23)

komponen abstraknya. Misalnya terdapat komponen TListView turunan TCustomListView, yang pada deklarasinya hanya mengubah visibilitas anggota-anggota TCustomListView yang protected menjadi published. Dengan antarmuka kelas, tidak perlu dilakukan hal seperti itu. Cukup dibuat dua buah antarmuka untuk TCustomListView, yaitu TCustomListView dengan semua anggotanya hidden, dan TListView dengan semua anggotanya visible.

Penggunaan kata access dan bukan interface di sini dimaksudkan untuk mencadangkan dukungan abstraksi dengan interface.

Bentuk umum deklarasi antarmuka kelas adalah:

access <nama_kelas> [ <nama_antarmuka_kelas> ] begin

<daftar_anggota> end;

Graf sintaks untuk antarmuka kelas atau akses dapat dilihat pada Gambar 3.17.

access accessHeader begin accessMember ; end

accessMember hiddenMember visibleMember

hiddenMember hidden propertySignature methodSignature

visibleMember visible propertySignature methodSignature

accessHeader access className accessName

(24)

Contoh:

class TWinControl TCustomListView

property Items … ; property ViewStyle … ; end; access TCustomListView hidden Items; hidden ViewStyle; end;

access TCustomListView TListView

Items; ViewStyle;

end;

access TCustomListView TfixedStyleListView

visible Items; hidden ViewStyle;

end; 3.1.5 Ekspresi

Walaupun DOGI, seperti halnya bahasa pemrograman OOP lainnya, masih menggunakan gaya imperatif, namun cara penulisan kode programnya dibuat sedemikian rupa sehingga dapat mudah dipahami.

Setiap statement dalam DOGI merupakan sebuah ekspresi. Sebuah ekspresi merupakan operasi yang dilakukan terhadap sebuah objek, dengan mengirimkan pesan melalui metoda yang dimiliki objek tersebut. Satuan terkecil dari ekspresi hanya ada dua macam, yaitu objek dan metoda.

(25)

Suatu objek tunggal adalah elemen terkecil sebuah ekspresi. Objek tersebut dapat berupa objek dengan nama atau literal integer, floating-point, boolean, string, null, code atau array. Graf sintaks objek tunggal dapat dilihat pada Gambar 3.20.

Suatu term adalah bagian dari ekspresi yang dapat berupa objek, ekspresi lain di antara tanda kurung, properti dan pengiriman pesan. Berikut ini adalah kemungkinan bentuk-bentuk term. Graf sintaks untuk term dapat dilihat pada pada Gambar 3.19.

<objek_tunggal>

( <ekspresi> )

<term_lain>.<properti> <pengiriman_pesan>

Pengiriman pesan dapat berbentuk satu dari:

<term> [ <daftar_ekspresi> ]

<term> . <metoda> ( <daftar_ekspresi> ) <metoda> ( <daftar_ekspresi> )

. <metoda> ( <daftar_ekspresi> )

<operator> <objek_tunggal>

Sebuah ekspresi dapat berupa sebuah term maupun pengiriman pesan ekspresi kepada sebuah term. Graf sintaks untuk ekspresi dapat dilihat pada Gambar 3.18.

<term> <metoda> <ekspresi_lain> <term>

expr term method\ term

(26)

sendMsg term singleObject expr term property ) ( sendMsg term [ ] term . method ( ) . method argList argList ( argList ) term operator

Gambar 3.19 Graf sintaks untuk term

singleObject objectName className array code integer float string boolean null

Gambar 3.20 Graf sintaks untuk objek

Contoh-contoh ekspresi:

dogi.duduk().salam();

console << ”Hello” + “ “ + “world!”; e = (29 * 94)+(24-3*c);

if (a>b) then begin put() end else [ 4 ];

3.1.6 Package System

Package System berisi kelas-kelas dasar yang dipakai oleh DOGI. Package System tidak perlu diimpor secara eksplisit karena otomatis akan dipakai oleh kompiler DOGI. Setiap kelas dalam System memiliki dua buah antarmuka, yang

(27)

berbeda dengan awalan @. Antarmuka yang diberi awalan @ semua method dan propertinya bersifat hidden. Sebagai contoh, antarmuka void dan @void menunjuk pada kelas yang sama, berbeda dalam hal setiap anggota @void hidden dan ada anggota void yang bersifat visible. Selanjutnya hanya akan dibahas antarmuka yang bersifat visible.

A. Kelas void

Kelas void merupakan kelas induk dari semua kelas yang dibuat dalam program DOGI (seperi object dalam Java dan C#). Dinamakan void, dan bukan object, setidaknya dengan alasan-alasan berikut:

• Pada C, C++ dan Java void adalah tipe data yang tidak mengandung apa-apa. Perlakuan khusus terhadap void pada Java sepertinya tidak fair, karena sudah terdapat pembedaan kelas dengan tipe data, ditambah satu lagi “tipe data” void hanya untuk menunjukkan bahwa sebuah metoda tidak mengembalikan nilai. Karena itu dalam DOGI void dibuat sebagai kelas. Dan karena sifatnya yang tidak mengandung apa-apa, maka dibuatlah void sebagai kelas induk dari semuanya. Semua metoda dalam DOGI mengembalikan nilai. Jika tidak dituliskan secara eksplisit, nilai yang dikembalikan adalah #null.

• Istilah object lebih bersifat konkret. Sedangkan kelas merupakan abstraksi. Dengan demikian, istilah object seharusnya lebih tepat digunakan sebagai nama instance, daripada nama kelas.

(28)

• Berdasarkan filosofi creatio ex nihilo, atau Allah menciptakan segala sesuatu dari tidak ada menjadi ada. Demikian juga setiap kelas diturunkan dari “ketiadaan” void.

Konstruktor

Kelas void memiliki hanya satu konstruktor, yang dipanggil tanpa parameter. Tugasnya adalah menciptakan sebuah objek dari kelas yang memanggilnya.

Destruktor

Destruktor kelas void bertugas untuk menghapus objek yang telah dibuat menggunakan konstruktor. Destruktor hanya akan menghapus objek yang bersangkutan jika reference count dari objek tersebut telah mencapai nol. Dengan kata lain, tidak ada lagi nama yang menunjuk objek tersebut.

Metoda-metoda kelas void

Metoda-metoda dalam kelas void diperlihatkan dalam Tabel 3.3.

void self() mengacu pada instance yang sedang aktif, dengan akses kepada metoda-metoda kelas aktif

void base() mengacu pada instance yang sedang aktif, dengan akses kepada metoda-metoda kelas induk

int refcount() mengembalikan jumlah reference count int addRef() menambah reference count

int release() mengurangi reference count void = (void) sama dengan assign(void) void assign(void) mengkopi objek lain

void assignTo(void) menyediakan layanan jika objek lain berusaha mengkopi objek yang bersangkutan

void applyTo(void, int) menyediakan layanan jika objek lain berusaha melakukan operasi terhadap objek yang bersangkutan

void .refTo(void) mereferensikan nama pada suatu objek void .->(void) sama dengan refTo(void)

(29)

array : (void) menyediakan operasi bagi bentuk kondisi?a:b seperti pada bahasa C

void .return(void) mengembalikan alur program pada metoda pemanggil, dan mengembalikan suatu objek _if .if(bool) menguji suatu kondisi, digunakan untuk seleksi _loop while(code cond) perulangan dengan kondisi cond

_loop loop(int n) perulangan sebanyak nilai tertentu _loop for(int i, int a,

int b) perulangan dengan counter i, dari nilai a hingga b _loop foreach(void x,

array A) perulangan dengan membaca hingga akhir array array A dari awal

Tabel 3.3 Daftar metoda yang terdapat dalam kelas void

B. Kelas data

Kelas data dimaksudkan untuk menjadi kelas induk dari semua kelas yang bertugas menangani data atau bertindak sebagai tipe data. Kelas ini adalah turunan langsung dari void.

C. Kelas number

Kelas number dimaksudkan sebagai kelas induk dari kelas-kelas yang menangani bilangan, seperti int dan real.

D. Kelas int

Kelas int merupakan kelas yang bertugas menangani bilangan-bilangan integer. Literal integer merupakan instansiasi dari kelas int. Kelas ini merupakan turunan langsung dari number.

Metoda-metoda kelas int diperlihatkan pada Tabel 3.4.

int + () mengembalikan nilai tanpa perubahan int - () mengembalikan nilai negatifnya

int + (int) menjumlahkan dengan bilangan integer real + (real) menjumlahkan dengan bilangan real int – (int) mengurangkan dengan bilangan integer

(30)

real – (real) mengurangkan dengan bilangan real int * (int) mengalikan dengan bilangan integer real * (real) mengalikan dengan bilangan real real / (int) membagi dengan bilangan integer real / (real) membagi dengan bilangan real

bool == (int) menguji kesamaan dengan integer lain bool != (int) menguji ketaksamaan dengan integer lain bool > (int) menguji apakah lebih besar dari integer lain bool < (int) menguji apakah lebih kecil integer lain bool >= (int) menguji apakah lebih besar atau sama dengan

integer lain

bool <= (int) menguji apakah lebih kecil atau sama dengan integer lain

Tabel 3.4 Daftar metoda yang terdapat dalam kelas int

E. Kelas bool

Kelas bool adalah turunan dari data. Kelas ini berkaitan dengan literal boolean pada bahasa DOGI.

Metoda-metoda kelas bool diperlihatkan pada Tabel 3.5.

bool ! () mengembalikan negasi dari objek yang bersangkutan

bool & (bool) melakukan operasi konjungsi terhadap boolean lain

bool | (bool) melakukan operasi disjungsi terhadap boolean lain bool == (bool) menguji kesamaan dengan boolean lain

bool != (bool) menguji ketaksamaan dengan boolean lain void ? (void o) mengembalikan o jika objek bernilai benar, dan

#null jika salah

void ? (array a) mengembalikan elemen pertama dari a jika kondisi benar, dan elemen kedua dari a jika kondisi salah

Tabel 3.5 Daftar metoda yang terdapat dalam kelas bool

F. Kelas real

Kelas real digunakan untuk bilangan real, merupakan turunan dari kelas number.

(31)

Metoda-metoda kelas real diperlihatkan pada Tabel 3.6.

real + () mengembalikan nilai tanpa perubahan real - () mengembalikan nilai negatifnya real + (int) menjumlahkan dengan bilangan real real + (real) menjumlahkan dengan bilangan real real – (int) mengurangkan dengan bilangan real real – (real) mengurangkan dengan bilangan real real * (int) mengalikan dengan bilangan real real * (real) mengalikan dengan bilangan real real / (int) membagi dengan bilangan real real / (real) membagi dengan bilangan real bool == (real) menguji kesamaan dengan real lain bool != (real) menguji ketaksamaan dengan real lain bool > (real) menguji apakah lebih besar dari real lain bool < (real) menguji apakah lebih kecil real lain

bool >= (real) menguji apakah lebih besar atau sama dengan real lain

bool <= (real) menguji apakah lebih kecil atau sama dengan real lain

Tabel 3.6 Daftar metoda yang terdapat dalam kelas real

G. Kelas string

Kelas string merupakan turunan dari kelas data yang bertugas menangani data string.

Metoda-metoda kelas string diperlihatkan pada tabel Tabel 3.8Tabel 3.7. int length() mengembalikan panjang string

string + (string) menggabungkan dengan string lain bool == (string) menguji kesamaan dengan string lain bool != (string) menguji ketaksamaan dengan string lain

Tabel 3.7 Daftar metoda yang terdapat dalam kelas string

H. Kelas array

Kelas array merupakan turunan dari data yang berguna untuk menciptakan array.

(32)

Metoda-metoda kelas array diperlihatkan pada tabel Tabel 3.8. int count() mengembalikan banyaknya elemen array int setCount(int) menentukan banyaknya elemen array void item(int i) mengembalikan elemen ke i

void setItem(int i,

void object) mengganti elemen ke i dengan object

Tabel 3.8 Daftar metoda yang terdapat dalam kelas array

I. Kelas code

Kelas code juga adalah turunan dari kelas data, ialah kelas yang menginstansiasikan semua kode yang ditulis dalam blok [ .. ] untuk kode yang hanya terdiri dari sebuah ekspresi, atau ditulis dalam blok begin..end untuk kode yang terdiri dari nol atau lebih ekspresi.

Metoda-metoda kelas code diperlihatkan pada Tabel 3.9. code exec() mengeksekusi kode

void value() mengembalikan hasil eksekusi kode

array else(code) membentuk array yang terdiri dari dua elemen bertipe code, untuk digunakan dalam struktur seleksi menggunakan if.

Tabel 3.9 Daftar metoda yang terdapat dalam kelas code

J. Kelas control

Kelas control menurunkan kelas-kelas yang berguna dalam pembentukan struktur kontrol. Kelas control adalah turunan langsung dari kelas void.

K. Kelas _if

Kelas _if merupakan kelas turunan control yang bertugas untuk menangani struktur seleksi dengan menggunakan metoda if.

(33)

Kelas _if hanya memiliki sebuah metoda, yaitu then dalam dua bentuk, seperti diperlihatkan dalam Tabel 3.10.

bool .then (code c) jika bernilai benar, kerjakan c

bool .then (array a) jika bernilai benar, kerjakan elemen pertama dari a, dan jika tidak, kerjakan elemen kedua dari a.

Tabel 3.10 Daftar metoda yang terdapat dalam kelas _if

L. Kelas _loop

Kelas _loop merupakan kelas turunan control yang bertugas menangani struktur perulangan menggunakan metoda loop.

Metoda-metoda kelas _loop diperlihatkan dalam Tabel 3.11.

int .do(code) melakukan perulangan terhadap kode yang

diberikan, dan mengembalikan jumlah perulangan yang telah dilakukan

Tabel 3.11 Daftar metoda yang terdapat dalam kelas _loop

M. Kelas console

Kelas console adalah turunan dari kelas void, ialah kelas yang bertugas untuk menangani input/output.

Metoda-metoda kelas console diperlihatkan dalam Tabel 3.12. void .<< (void) menuliskan suatu objek pada console void .>> (string) membaca suatu string dari console void .>> (int) membaca suatu integer dari console void .>> (real) membaca suatu real dari console void .>> (bool) membaca suatu boolean dari console

void .writeln (void) menuliskan suatu objek pada console (+newline) void .readln (string) membaca suatu string dari console (+newline) void .readln (int) membaca suatu integer dari console (+newline) void .readln (real) membaca suatu real dari console (+newline) void .readln (bool) membaca suatu boolean dari console (+newline)

(34)

3.2 Perancangan kompiler DOGI

Seperti telah disebutkan pada 1.2, untuk penyederhanaan perancangan kompiler, maka kompiler DOGI disatukan dengan eksekutornya (virtual machine). Kedua modul ini disatukan menjadi sebuah program. Untuk selanjutnya frasa “program DOGI” menunjuk pada program yang akan dibuat sebagai gabungan kompiler DOGI dan virtual machine.

Program DOGI dibuat seluruhnya dengan C++, dengan bantuan program Flex untuk membuat scanner, serta Bison untuk membuat parser. Program DOGI versi Windows dikompilasi menggunakan Borland C++ 5.6.4 for Win32. Kompilasi dengan Minimalist GNU for Win32 versi 2.0.0 juga berhasil dilakukan. Untuk versi Linux dikompilasi menggunakan GNU C++ Compiler.

3.2.1 Spesifikasi rancangan

Spesifikasi komputer yang digunakan dalam pembuatan dan pengujian program DOGI adalah:

• Prosesor Pentium III 733 MHz • RAM 320MB

• 2 Hard Disk berukuran 80GB dan 40GB • 2 Sistem operasi:

a. Windows XP Professional Edition

b. Linux dengan paket distribusi Mandrake 9.1

(35)

3.2.2 Antarmuka pemakai

Program DOGI dijalankan dari command-line interpreter, dengan menuliskan:

dogi { [<opsi>] } [<file_kode_sumber>]

Opsi yang disediakan adalah seperti diperlihatkan pada Tabel 3.13 ( case-insensitive). Jika kode sumber mengandung kesalahan, akan ditampilkan posisi dan jenis kesalahan yang terjadi.

-i menampilkan setiap instruksi yang sedang dieksekusi

-s menampilkan state pada setiap eksekusi instruksi -e menampilkan isi stack pada setiap eksekusi

instruksi

-d gabungan dari -i, -s, dan -e

-v menampilkan daftar isi package dalam file -x<accessname> membuat dan mengeksekusi instance dari akses

bernama <accessname>

Tabel 3.13 Daftar opsi yang tersedia dalam program DOGI

3.2.3 Scanner

Kode sumber scanner DOGI (dogi.lpp) dikompilasi dengan Flex untuk menghasilkan dogi.yy.cpp yang merupakan program dalam bahasa C++. Selanjutnya, dogi.yy.cpp dikompilasi menggunakan kompiler C++.

Kode sumber scanner DOGI dapat dilihat pada Lampiran B. 3.2.4 Parser

Kode sumber parser DOGI (dogi.ypp) dikompilasi dengan Bison untuk menghasilkan dogi.tab.hpp dan dogi.tab.cpp yang merupakan program dalam bahasa C++, untuk dikompilasi kembali dengan kompiler C++.

(36)

Kode sumber parser DOGI dapat dilihat pada Lampiran B, dan tata bahasanya dalam format BNF dapat dilihat pada Lampiran A. Dituliskan dalam format BNF dan bukan EBNF karena Bison hanya dapat mengenali BNF.

3.2.5 Aturan semantik tata bahasa DOGI

Tidak setiap aturan semantik produksi tata bahasa DOGI akan dibahas di sini. Hanya definisi metoda dan ekspresi yang akan dibahas, karena merupakan bagian yang berhubungan erat dengan pembentukan kode antara. Setiap aturan semantik dideskripsikan dalam bentuk pseudocode.

A. Definisi metoda dalam kelas

Produksi methodCode → = expr

methodCode = …

for index=number of arguments downto 1 do

put POPA argumentindex

endfor

if (method is not class method) put POPCTX

endif put KEEP … expr put RET

Produksi methodCode → begin exprList end

methodCode begin …

for index=number of arguments downto 1 do

put POPA argumentindex

(37)

if (method is not class method) put POPCTX endif put KEEP … exprList end put PUSHN put RET B. Ekspresi

Baik expr, term, object, sendMsg maupun literal memiliki atribut-atribut sebagai berikut:

• class untuk menyatakan tipe yang dikembalikan oleh nonterminal-nonterminal tersebut.

• instance untuk menyatakan apakah nonterminal adalah kelas atau instance.

Sedangkan method memiliki atribut instruction yang adalah instruksi yang diwakili oleh metoda yang bersangkutan secara langsung.

Produksi expr → expr nextExprList

expr expr … put FLUSH … nextExprList

Produksi expr → term methodName expr

if (term.class has method w/signature methodName(expr)) then

(38)

if (method is instruction) then

put method.instruction

else

put CALL(

term.class,

index of method in term.class)

endif

else

if (method is class method) then

if (method is instruction) then

put method.instruction

else

put CALL(

term.class,

index of method in term.class)

endif

else

Error Message: Not class method. endif

endif else

Error Message: method not found.

Endif

Produksi object → objectName

if (objectName in localList) then

put PUSHL (index of objectName in localList) object.class=class of objectName

object.instance=true

elseif (objectName in argList) then

put PUSHA (index of objectName in argList) object.class=class of objectName

(39)

elseif (objectName in fieldList) then

put PUSHO (index of objectName in fieldList) object.class=class of objectName

object.instance=true

elseif (objectName is className) then

object.class=class of objectName

object.instance=false

else

Error Message: objectName undeclared.

Endif

Produksi object → integer

put PUSHI integer.value Produksi object → floatingPoint

put PUSHF floatingPoint.value Produksi object → boolean

put PUSHB boolean.value Produksi object → string

put PUSHS string.value Produksi object → code

(40)

Produksi sendMsg → term . methodName (sendArgList)

if (term.class has method w/signature

methodName(sendArgList)) then

if (term.instance = true) then if (method is instruction) then

put method.instruction

else

put CALL(

term.class,

index of method in term.class)

endif

else

if (method is class method) then

if (method is instruction) then

put method.instruction

else

put CALL(

term.class,

index of method in term.class)

endif

else

Error Message: Not class method. endif

endif else

Error Message: method not found.

Endif

Produksi sendMsg → methodName (sendArgList) dan sendMsg → . methodName (sendArgList)

if (current.class has method w/signature

(41)

if (method is not class method) then put SELF

endif

if (method is instruction) then

put method.instruction

else

put CALL(

current.class,

index of method in current.class)

endif

else

Error Message: method not found.

Endif

Produksi sendMsg → operatorName object

if (object.class has method w/signature operatorName()) then

if (method is instruction) then

put method.instruction

else

put CALL(

object.class,

index of method in object.class)

endif

else

Error Message: method not found.

Endif C. Literal code

Produksi code → begin exprList end

(42)

push current address to address stack put PUSHC (current address+4)

put JMP (-1) … exprList end put FLUSH put PUSHN put RETC

addr = pop address stack

replace code at addr+3 with current address

Produksi code → [ expr ]

code begin …

push current address to address stack put PUSHC (current address+4)

put JMP (-1) … exprList end put RETC

addr = pop address stack

replace code at addr+3 with current address

3.3 Perancangan DOGIVM (DOGI Virtual Machine)

3.3.1 Instruksi-instruksi dasar DOGIVM

Instruksi-instruksi yang terdapat pada DOGIVM diperlihatkan pada Tabel 3.14. Panjang instruksi menyatakan panjang instruksi dalam satuan doubleword (32 bit), jumlah pop menyatakan banyaknya anggota stack yang diambil oleh instruksi tersebut, dan return menyatakan banyaknya objek yang didorong oleh instruksi tersebut ke dalam stack.

(43)

instruksi panjang (double

word)

jumlah

pop return deskripsi NOP 1 tidak ada operasi

PUSH o 2 1 dorong objek o ke dalam stack PUSHL l 2 1 dorong objek lokal l ke dalam stack PUSHA a 2 1 dorong objek argumen a ke dalam stack PUSHI i 2 1 dorong objek integer bernilai i ke dalam stack PUSHF f 2 1 dorong objek real bernilai f ke dalam stack PUSHB b 2 1 dorong objek boolean bernilai b ke dalam stack PUSHS s 2 1 dorong objek string bernilai s ke dalam stack

PUSHC a 2 1 dorong objek code yang menunjuk alamat a ke dalam stack

PUSHN 1 1 dorong objek null ke dalam stack

POP o 2 1 ambil objek dari stack dan asosiasikan ke objek o POPL l 2 1 ambil objek dari stack dan asosiasikan ke objek lokal

l

POPA a 2 1 ambil objek dari stack dan asosiasikan ke objek argumen a

POPCTX 1 1 ambil objek dari stack dan asosiasikan ke objek konteks

JMP a 2 lompat ke alamat a

IFENTRY 1 1 1 buat suatu instance _if berdasarkan kondisi yang diberikan objek pada puncak stack

IFT 1 2 1 jalankan kode pada puncak stack jika benar IFTE 1 2 1 pilih kode yang akan dijalankan dari array pada

puncak stack

LOOP 1 1 buat suatu instance _loop

LOOPW 1 1 1 buat suatu instance _loop berdasarkan yang diberikan objek pada puncak stack

LOOPI 1 1 1 buat suatu instance _loop berdasarkan jumlah yang diberikan objek pada puncak stack

LOOPA 1 2 1 buat suatu instance _loop berdasarkan array yang diberikan objek pada puncak stack, dan objek di bawahnya untuk menampung elemen array LOOPF 1 3 1 buat suatu instance _loop berdasarkan batas yang

diberikan objek pada puncak stack dan objek di bawahnya

LOOPDO 1 2 1 eksekusi kode yang ada pada puncak stack CALL c m 3 memanggil metoda m dari kelas c

CALLC a 2 mengeksekusi kode pada alamat a

NEW c m 3 1 membuat instance dari kelas c dengan konstruktor m KILL 1 1 1 mendealokasikan objek pada puncak stack

RET 1 kembali pada alamat pemanggil (CALL) RETC 1 kembail pada alamat pemanggil (CALLC) ENDX 1 menandai akhir dari kode

END 1 menandai akhir dari kode KEEP 1 1 menandai stack dengan pembatas

FLUSH 1 * menghapus isi stack dari puncak hingga pembatas yang dibuat dengan KEEP

DISCONST 1 1 1 mengembalikan #true jika objek pada puncak stack dibuat dari literal

(44)

pada puncak stack

SUB 1 2 1 mengembalikan hasil pengurangan dari dua objek pada puncak stack

MUL 1 2 1 mengembalikan hasil perkalian dari dua objek pada puncak stack

DIV 1 2 1 mengembalikan hasil pembagian dari dua objek pada puncak stack

NEG 1 1 1 mengembalikan negasi dari objek pada puncak stack (bilangan)

POS 1 1 1 tidak ada operasi

AND 1 2 1 mengembalikan hasil operasi and dari dua objek pada puncak stack

OR 1 2 1 mengembalikan hasil operasi or dari dua objek pada puncak stack

NOT 1 1 1 mengembalikan negasi dari objek pada puncak stack (boolean)

ASSIGN 1 2 1 mengkopi dua objek pada puncak stack REFTO 1 2 1 mereferensikan nama objek pada objek lain ADDREF 1 1 1 menambah reference count

RELEASE 1 1 1 mengurangi reference count REFCOUNT 1 1 1 mengembalikan reference count BASE 1 1 1 mendorong instance ke dalam stack SELF 1 1 1 mendorong instance ke dalam stack

ALTER 1 2 1 mendorong array berisi dua objek pada puncak stack CMPE 1 2 1 membandingkan dua objek pada puncak stack, dan

mengembalikan #true jika keduanya sama, dan #false jika sebaliknya

CMPNE 1 2 1 membandingkan dua objek pada puncak stack, dan mengembalikan #true jika keduanya tidak sama, dan #false jika sebaliknya

CMPG 1 2 1 membandingkan dua objek pada puncak stack, dan mengembalikan #true jika nilai objek pertama > nilai objek kedua, dan #false jika sebaliknya CMPL 1 2 1 membandingkan dua objek pada puncak stack, dan

mengembalikan #true jika nilai objek pertama < nilai objek kedua, dan #false jika sebaliknya CMPGE 1 2 1 membandingkan dua objek pada puncak stack, dan

mengembalikan #true jika nilai objek pertama ≥ nilai objek kedua, dan #false jika sebaliknya CMPLE 1 2 1 membandingkan dua objek pada puncak stack, dan

mengembalikan #true jika nilai objek pertama ≤ nilai objek kedua, dan #false jika sebaliknya SLEN 1 1 1 mengembalikan panjang string pada puncak stack ARRSCNT 1 2 1 mengeset jumlah elemen array pada puncak stack ARRGCNT 1 1 1 mengembalikan jumlah elemen array pada puncak

stack

ARRSITEM 1 3 1 mengeset elemen array pada puncak stack ARRGITEM 1 2 1 mengembalikan elemen array pada puncak stack CONOUT 1 1 1 mencetak representasi dari objek pada puncak stack CONIN 1 1 1 membaca representasi objek dari console dan

mendorongnya ke dalam stack

CONOUTN 1 1 1 mencetak representasi dari objek pada puncak stack (+newline)

(45)

CONINN 1 1 1 membaca representasi objek dari console dan mendorongnya ke dalam stack

CDEXEC 1 1 1 mengeksekusi kode yang terdapat pada puncak stack CDVAL 1 1 1 mengembalikan nilai yang dihasilkan oleh kode CDELSE 1 2 1 membentuk array berisi dua objek pada puncak stack CDQT 1 2 1 mengembalikan objek pada puncak stack jika

bernilai benar

CDQTE 1 2 1 mengembalikan objek pertama pada array pada puncak stack jika bernilai benar

Tabel 3.14 Daftar instruksi DOGIVM

3.3.2 Siklus eksekusi instruksi

Siklus eksekusi kode antara DOGI diperlihatkan dalam Gambar 3.21. Instruksi CALL

• Dorong state konteks ke dalam state stack • Kosongkan state konteks,

• Set posisi pada state konteks pada alamat metoda Instruksi RET

• Pop state konteks dari state stack 3.3.3 State

Suatu state dalam DOGIVM terdiri dari:

• Sebuah daftar semua objek yang diinstansiasikan sejak program berjalan, • Sebuah state konteks – yaitu informasi mengenai posisi eksekusi, instance

yang sedang aktif, semua field yang terdapat pada instance tersebut, argumen-argumen metoda yang sedang dieksekusi, dan objek-objek lokal metoda tersebut,

(46)

• Sebuah state stack yang menyimpan state konteks ketika ada pemanggilan suatu metoda,

• Sebuah stack evaluasi, yang berisi objek-objek untuk digunakan dalam evaluasi, dan objek hasil evaluasi suatu ekspresi.

(47)

Ambil instruksi Eksekusi instruksi Majukan posisi pembacaan Stack kosong? Tidak Ya Reset posisi &

kosongkan stack

start

selesai

Gambar

Gambar 3.2 Graf sintaks untuk digit heksadesimal
Gambar 3.4 Graf sintaks untuk literal floating-point
Tabel 3.1 Karakter-karakter escape yang berlaku
Gambar 3.5 Graf sintaks untuk karakter tunggal
+7

Referensi

Dokumen terkait

[r]

Pati teroksidasi menggunakan NaOCl 9 % waktu oksidasi 60 menit.. Pati teroksidasi menggunakan NaOCl 12 % waktu oksidasi

Konsultan pengawas bertanggung jawab penuh kepada Pemimpin Pekerjaan bahwa hasil pelaksanaan pekerjaan oleh Penyedia Jasa Pemborongan benar-benar sesuai ketentuan kontrak

•   Google Scholar è Impact Factor (profil jurnal: h-index, i10- index, Cita&gt;on analysis). •  EBSCO , Gale, Proquest, CABI è aggregator

PROBLEMATIKA ORANG TUA DALAM MENGASUH ANAK TUNAGRAHITA Universitas Pendidikan Indonesia | repository.upi.edu | perpustakaan.upi.edu.

Jadual 2: Senarai Kursus yang ditawarkan dalam PISMP SEJARAH dengan nama pensyarah yang

Alamat Email : diharto72 pada domain gmail.com atau diharto pada domain staff.unnes.ac.id. Pangkat/Golongan/Ruang :

Oleh itu, dapatan kajian melalui kaedah pengumpulan data soal selidik telah menunjukkan bahawa hampir keseluruhan responden kajian sangat bersetuju bahawa dengan penggunaan